Почему правильный сценарий оболочки выдает завернутое/усеченное / поврежденное сообщение об ошибке? [дубликат]


На этот вопрос уже есть ответ здесь:

У меня есть скрипт оболочки с командой, которая, кажется, должна работать, но вместо этого она терпит неудачу с нечетным завернутым/усеченным/поврежденным сообщением об ошибке. Пример:

$ ls -l myfile
-rw-r----- 1 me me 0 Aug  7 12:36 myfile
$ cat myscript 
ls -l myfile
$ bash myscript
: No such file or directory

Файл явно существует, но даже если бы я этого не сделал, это это сообщение об ошибке, которое я обычно получаю:

$ ls -l idontexist
ls: cannot access idontexist: No such file or directory
Обратите внимание, что он включает имя инструмента ls, строку сообщения и имя файла, в то время как мой-нет.

Вот что я получу, если попытаюсь использовать mysql вместо этого. Сообщение об ошибке выглядит так, как будто оно было завернуто, и теперь начинается с цитаты:

Command:  mysql -h myhost.example.com
Expected: ERROR 2005 (HY000): Unknown MySQL server host 'myhost.example.com' (0)
Actual:   ' (0) 2005 (HY000): Unknown MySQL server host 'myhost.example.com

И вот моя тривиальная команда ssh, которая должна работать или, по крайней мере, давать нормальное сообщение об ошибке, но которая вместо этого оборачивается, чтобы начать с двоеточия и заканчивается странным стук:

Command:  ssh myhost
Expected: ssh: Could not resolve hostname myhost: Name or service not known
Actual:   : Name or service not knownname myhost

Почему это происходит и как это исправить?

1 7

1 ответ:

TL; DR: ваш скрипт или данные имеют окончания строк CRLF в стиле Windows.

Преобразовать в Unix стиль, удалив возврат каретки.


Как проверить, есть ли у моего скрипта или данных возврат каретки?

Они обнаруживаются как ^M в выводе cat -v yourscript:

$ cat -v myscript
ls -l myfile^M

Если в вашем скрипте их нет, ваши данные могут - особенно при чтении из файлов ini / csv или curl:

hostname=$(curl https://example.com/loginhost.txt)
ssh "$hostname"            # Shows strange error
echo "$hostname" | cat -v  # Shows myhost^M

Как мне удалить их?

Установите редактор для сохранения файла. с окончаниями строк Unix, они же " Терминаторы строк "или" символы конца строки", и повторно сохранить его.

Вы также можете удалить их из командной строки с помощью dos2unix yourscript или cat yourscript | tr -d '\r' > fixedscript.

Если источник найден в ваших данных, вы можете передать его через tr -d '\r':

hostname=$(curl https://example.com/loginhost.txt | tr -d '\r')

Почему возврат каретки вызывает странные сообщения об ошибках?

Символ "возврата каретки", он же CR или \r, заставляет курсор переместиться в начало строки и продолжить печать оттуда. Другими словами, она начинается переписываю строку с самого начала. Вот почему они странно оборачиваются:

Intended:     ssh: Could not resolve hostname myhost\r: Name or service not known

Written:      ssh: Could not resolve hostname myhost\r
Overwritten:  : Name or service not known
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                  
Result:       : Name or service not knownname myhost