Eof error in linux

Tar error: Unexpected EOF in archive

I tar a directory full of JPEG images:

When I untar the archive:

Looking at the output, it fails in the middle of one particular JPEG image.

What am I doing wrong?

5 Answers 5

Interesting. I have a few questions which may point out the problem.

1/ Are you untarring on the same platform as you’re tarring on? They may be different versions of tar (e.g., GNU and old-unix)? If they’re different, can you untar on the same box you tarred on?

2/ What happens when you simply gunzip myarchive.tar.gz? Does that work? Maybe your file is being corrupted/truncated. I’m assuming you would notice if the compression generated errors, yes?

Based on the GNU tar source, it will only print that message if find_next_block() returns 0 prematurely which is usually caused by truncated archive.

May be you have ftped the file in ascii mode instead of binary mode ? If not, this might help.

And then untar the resulting tar file using

Hope this helps.

I had a similar problem with truncated tar files being produced by a cron job and redirecting standard out to a file fixed the issue.

From talking to a colleague, cron creates a pipe and limits the amount of output that can be sent to standard out. I fixed mine by removing -v from my tar command, making it much less verbose and keeping the error output in the same spot as the rest of my cron jobs. If you need the verbose tar output, you’ll need to redirect to a file, though.

In my case, I had started untar before the uploading of the tar file was complete.

I had a similar error, but in my case the cause was file renaming. I was creating a gzipped file file1.tar.gz and repeatedly updating it in another tarfile with tar -uvf ./combined.tar ./file1.tar.gz . I got the unexpected EOF error when after untarring combined.tar and trying to untar file1.tar.gz .

I noticed there was a difference in the output of file before and after tarring:

So, it appears that the file had a different name when I originally created combined.tar , and using the tar update function doesn’t overwrite the metadata for the gzipped filename. The solution was to recreate combined.tar from scratch instead of updating it.

I still don’t know exactly what happened, since changing the name of a gzipped file doesn’t normally break it.

Источник

getting unexpected EOF error

I am getting the following error

Can somebody help what is the syntax error here’

2 Answers 2

The syntax error itself is caused by the backtick appearing on the same line as EOF , as indicated in Kusalananda’s answer. However, this script has other problems, so in the interest of better shell scripting abilities everywhere, let’s take a closer look.

First misconception: As you reference «$» , you seem to be under the impression that you have created an array. You haven’t. To do that, you need to use parentheses in your variable assignment.

Similarly, if you do use an array, you don’t need to use ls . The globs will expand directly to become the elements of the array.

This is fortunate, because you should never parse the output of ls , anyway; see:

So the right way to set the variable losystem as an array whose elements are the files and directories inside /appl/vortex/archive/cons/ is:

Your echo command (on the second line) is missing a closing > .

Читайте также:  Windows hello не включается

Also, you may want to use printf here instead:

The for loop is correct for iterating over the elements of the Bash array losystem , so given that you’ve made the above corrections, you can use it unchanged.

However, you don’t need to set an array, and it’s much more idiomatic (cleaner, more intuitive) to directly state the file glob in the for loop:

This also has the advantage of being POSIX-compliant, since it doesn’t rely on Bash arrays, so it can work in a wider variety of shells (i.e. it’s more portable).

The next part of your script is even trickier to review, because it appears that you are setting filetype to the output of the isql command, but then you don’t do anything with this output except print it—badly formatted—with echo . (Again, see Why is printf better than echo?)

The obvious approach is not to set the variable at all, but just run the command directly; it will print its own output, which is all you really wanted anyway:

Note that I am not familiar with isql , so I do not attest the correctness of this command. It is the command you yourself wrote, unchanged. It may or may not be correct.

The strangest thing about this script, though, is the fact that you are setting indsystem to each element of the losystem array (or trying to), but then you never reference the value of «$indsystem» .

This is the «elephant in the room.» I can’t fix this logic, because I can’t read your mind. It’s not at all clear what you are trying to do.

I can think of several different possibilities:

  1. Perhaps you are trying to run the isql command on each file in the cons directory. (In which case the isql command should reference the indsystem variable somewhere, and you should check that you don’t run it on directories.)
  2. Perhaps you want to run the isql command exactly once, but only if the cons directory is not empty.
  3. Perhaps you want to run the isql command without referencing indsystem , but run it the same way multiple times, exactly as many times as there are files/directories in the cons directory. (This is what my fixed version of the code will do, but it doesn’t make a whole lot of sense.)

None of these possibilities are obviously correct, so I can’t conclude what the script is actually trying to do.

Still, I hope this was helpful in learning more about shell scripting. To learn Bash scripting properly, I recommend the Wooledge Bash Guide.

I will also comment that in my professional experience, I have found that a shell script with as many problems as this one usually has architectural/design problems at a higher level, and that usually it is necessary to completely review the supposed reason why the script is needed in the first place to get a truly workable solution.

Источник

EOF — это не символ

Недавно я читал книгу «Компьютерные системы: архитектура и программирование. Взгляд программиста». Там, в главе про систему ввода-вывода Unix, авторы упомянули о том, что в конце файла нет особого символа EOF .

Если вы читали о системе ввода-вывода Unix/Linux, или экспериментировали с ней, если писали программы на C, которые читают данные из файлов, то это заявление вам, вероятно, покажется совершенно очевидным. Но давайте поближе присмотримся к следующим двум утверждениям, относящимся к тому, что я нашёл в книге:

  1. EOF — это не символ.
  2. В конце файлов нет некоего особого символа.

Что же такое EOF ?

EOF — это не символ

Почему кто-то говорит или думает, что EOF — это символ? Полагаю, это может быть так из-за того, что в некоторых программах, написанных на C, можно найти код, в котором используется явная проверка на EOF с использованием функций getchar() и getc() .

Читайте также:  Windows не видит внешнего hdd

Это может выглядеть так:

Если заглянуть в справку по getchar() или getc() , можно узнать, что обе функции считывают следующий символ из потока ввода. Вероятно — именно это является причиной возникновения заблуждения о природе EOF . Но это — лишь мои предположения. Вернёмся к мысли о том, что EOF — это не символ.

А что такое, вообще, символ? Символ — это самый маленький компонент текста. «A», «a», «B», «b» — всё это — разные символы. У символа есть числовой код, который в стандарте Unicode называют кодовой точкой. Например — латинская буква «A» имеет, в десятичном представлении, код 65. Это можно быстро проверить, воспользовавшись командной строкой интерпретатора Python:

Или можно взглянуть на таблицу ASCII в Unix/Linux:

Выясним, какой код соответствует EOF , написав небольшую программу на C. В ANSI C константа EOF определена в stdio.h , она является частью стандартной библиотеки. Обычно в эту константу записано -1 . Можете сохранить следующий код в файле printeof.c , скомпилировать его и запустить:

Скомпилируем и запустим программу:

У меня эта программа, проверенная на Mac OS и на Ubuntu, сообщает о том, что EOF равняется -1 . Есть ли какой-нибудь символ с таким кодом? Тут, опять же, можно проверить коды символов в таблице ASCII, можно взглянуть на таблицу Unicode и узнать о том, в каком диапазоне могут находиться коды символов. Мы же поступим иначе: запустим интерпретатор Python и воспользуемся стандартной функцией chr() для того, чтобы она дала бы нам символ, соответствующий коду -1 :

Как и ожидалось, символа с кодом -1 не существует. Значит, в итоге, EOF , и правда, символом не является. Переходим теперь ко второму рассматриваемому утверждению.

В конце файлов нет некоего особого символа

Может, EOF — это особенный символ, который можно обнаружить в конце файла? Полагаю, сейчас вы уже знаете ответ. Но давайте тщательно проверим наше предположение.

Возьмём простой текстовый файл, helloworld.txt, и выведем его содержимое в шестнадцатеричном представлении. Для этого можно воспользоваться командой xxd :

Как видите, последний символ файла имеет код 0a . Из таблицы ASCII можно узнать о том, что этот код соответствует символу nl , то есть — символу новой строки. Это можно выяснить и воспользовавшись Python:

Так. EOF — это не символ, а в конце файлов нет некоего особого символа. Что же такое EOF ?

Что такое EOF?

EOF (end-of-file) — это состояние, которое может быть обнаружено приложением в ситуации, когда операция чтения файла доходит до его конца.

Взглянем на то, как можно обнаруживать состояние EOF в разных языках программирования при чтении текстового файла с использованием высокоуровневых средств ввода-вывода, предоставляемых этими языками. Для этого напишем очень простую версию cat , которая будет называться mcat . Она побайтно (посимвольно) читает ASCII-текст и в явном виде выполняет проверку на EOF . Программу напишем на следующих языках:

  • ANSI C
  • Python 3
  • Go
  • JavaScript (Node.js)

Вот репозиторий с кодом примеров. Приступим к их разбору.

ANSI C

Начнём с почтенного C. Представленная здесь программа является модифицированной версией cat из книги «Язык программирования C».

Вот некоторые пояснения, касающиеся вышеприведённого кода:

  • Программа открывает файл, переданный ей в виде аргумента командной строки.
  • В цикле while осуществляется копирование данных из файла в стандартный поток вывода. Данные копируются побайтово, происходит это до тех пор, пока не будет достигнут конец файла.
  • Когда программа доходит до EOF , она закрывает файл и завершает работу.

Python 3

В Python нет механизма явной проверки на EOF , похожего на тот, который имеется в ANSI C. Но если посимвольно читать файл, то можно выявить состояние EOF в том случае, если в переменной, хранящей очередной прочитанный символ, будет пусто:

Запустим программу и взглянём на возвращаемые ей результаты:

Вот более короткая версия этого же примера, написанная на Python 3.8+. Здесь используется оператор := (его называют «оператор walrus» или «моржовый оператор»):

Запустим этот код:

В Go можно явным образом проверить ошибку, возвращённую Read(), на предмет того, не указывает ли она на то, что мы добрались до конца файла:

JavaScript (Node.js)

В среде Node.js нет механизма для явной проверки на EOF . Но, когда при достижении конца файла делается попытка ещё что-то прочитать, вызывается событие потока end.

Читайте также:  Сетевой принтер отключен хотя он включен windows 10

Низкоуровневые системные механизмы

Как высокоуровневые механизмы ввода-вывода, использованные в вышеприведённых примерах, определяют достижение конца файла? В Linux эти механизмы прямо или косвенно используют системный вызов read(), предоставляемый ядром. Функция (или макрос) getc() из C, например, использует системный вызов read() и возвращает EOF в том случае, если read() указывает на возникновение состояния достижения конца файла. В этом случае read() возвращает 0 . Если изобразить всё это в виде схемы, то получится следующее:

Получается, что функция getc() основана на read() .

Напишем версию cat , названную syscat , используя только системные вызовы Unix. Сделаем мы это не только из интереса, но и из-за того, что это вполне может принести нам какую-то пользу.

Вот эта программа, написанная на C:

В этом коде используется тот факт, что функция read() , указывая на достижение конца файла, возвращает 0 .

Вот та же программа, написанная на Python 3:

Вот — то же самое, написанное на Python 3.8+:

Запустим и этот код:

Итоги

  • EOF — это не символ.
  • В конце файлов нет некоего особого символа.
  • EOF — это состояние, о котором сообщает ядро, и которое может быть обнаружено приложением в том случае, когда операция чтения данных доходит до конца файла.
  • В ANSI C EOF — это, опять же, не символ. Это — константа, определённая в stdio.h , в которую обычно записано значение -1.
  • «Символ» EOF нельзя найти в таблице ASCII или в Unicode.

Уважаемые читатели! А вы знаете о каких-нибудь более или менее широко распространённых заблуждениях из мира компьютеров?

Источник

How does «cat Asked 11 years, 6 months ago

I needed to write a script to enter multi-line input to a program ( psql ).

After a bit of googling, I found the following syntax works:

This correctly constructs the multi-line string (from BEGIN; to END; , inclusive) and pipes it as an input to psql .

But I have no idea how/why it works, can some one please explain?

I’m referring mainly to cat , I know > outputs to a file, >> appends to a file, reads input from file.

What does exactly do?

And is there a man page for it?

9 Answers 9

The cat syntax is very useful when working with multi-line text in Bash, eg. when assigning multi-line string to a shell variable, file or a pipe.

Examples of cat syntax usage in Bash:

1. Assign multi-line string to a shell variable

The $sql variable now holds the new-line characters too. You can verify with echo -e «$sql» .

2. Pass multi-line string to a file in Bash

The print.sh file now contains:

3. Pass multi-line string to a pipe in Bash

The b.txt file contains bar and baz lines. The same output is printed to stdout .

This is called heredoc format to provide a string into stdin. See https://en.wikipedia.org/wiki/Here_document#Unix_shells for more details.

Here Documents

This type of redirection instructs the shell to read input from the current source until a line containing only word (with no trailing blanks) is seen.

All of the lines read up to that point are then used as the standard input for a command.

The format of here-documents is:

No parameter expansion, command substitution, arithmetic expansion, or pathname expansion is performed on word. If any characters in word are quoted, the delimiter is the result of quote removal on word, and the lines in the here-document are not expanded. If word is unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion. In the latter case, the character sequence \ is ignored, and \ must be used to quote the characters \ , $ , and ` .

If the redirection operator is , then all leading tab characters are stripped from input lines and the line containing delimiter. This allows here-documents within shell scripts to be indented in a natural fashion.

Источник

Оцените статью