¿Por qué un script de shell correcto daría un mensaje de error envuelto / truncado / dañado?

Tengo un script de shell con un comando que parece que debería funcionar, pero en su lugar falla con un mensaje de error impar envuelto / truncado / dañado. Ejemplo:

$ 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 

El archivo existe claramente, pero incluso si no lo hice, este es el tipo de mensaje de error que normalmente recibiría:

 $ ls -l idontexist ls: cannot access idontexist: No such file or directory 

Observe cómo incluye el nombre de la herramienta ls , una cadena de mensaje y el nombre del archivo, mientras que el mío no.

Esto es lo que obtengo si trato de usar mysql lugar. El mensaje de error parece haberse envuelto y ahora comienza con una cita:

 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 

Y aquí está mi comando ssh trivial que debería funcionar, o al menos dar un mensaje de error normal, pero que, en cambio, está envuelto para comenzar con dos puntos y termina con un extraño cloqueo:

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

¿Por qué sucede esto y cómo lo soluciono?

TL; DR: Su secuencia de comandos o datos tienen terminaciones de línea CRLF estilo Windows.

Convierta a estilo Unix eliminando los retornos de carro.


¿Cómo puedo verificar si mi script o datos tienen retornos de carro?

Son detectables como ^M en la salida de cat -v yourscript :

 $ cat -v myscript ls -l myfile^M 

Si su script no los tiene, sus datos podrían, especialmente si lee archivos ini / csv o curl :

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

¿Cómo los elimino?

Configure su editor para guardar el archivo con terminaciones de línea Unix, también conocidas como “terminadores de línea” o “caracteres de fin de línea”, y vuelva a guardarlo.

También puede eliminarlos de una línea de comando con dos2unix yourscript o cat yourscript | tr -d '\r' > fixedscript cat yourscript | tr -d '\r' > fixedscript .

Si se encuentra en sus datos, puede canalizar su fuente a través de tr -d '\r' :

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

¿Por qué los retornos de carro causan mensajes de error extraños?

El carácter “retorno de carro”, también conocido como CR o \r , hace que el cursor se mueva al comienzo de la línea y continúe imprimiendo desde allí. En otras palabras, comienza a sobrescribir la línea desde el principio. Es por eso que se envuelven de manera extraña:

 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