Perché uno script di shell corretto darebbe un messaggio di errore avvolto / troncato / corrotto?

Ho uno script di shell con un comando che sembra dovrebbe funzionare, ma invece fallisce con un messaggio di errore dispari / troncato / corrotto. Esempio:

$ 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 

Il file esiste chiaramente, ma anche se non lo facessi, questo è il tipo di messaggio di errore che otterrei normalmente:

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

Notate come include il nome dello strumento ls , una stringa di messaggio e il nome del file mentre il mio no.

Ecco cosa ottengo se provo a usare mysql . Il messaggio di errore sembra essere stato incartato e ora inizia con una citazione:

 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 

Ed ecco il mio comando ssh banale che dovrebbe funzionare, o almeno dare un normale messaggio di errore, ma che invece è avvolto per iniziare con due punti e termina con uno strano clobbering:

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

Perché succede e come lo risolvo?

TL; DR: lo script o i dati hanno terminazioni di riga CRLF in stile Windows.

Converti in stile Unix cancellando i ritorni a capo.


Come posso verificare se il mio script o i miei dati hanno ritorni a capo?

Sono rilevabili come ^M nell’output di cat -v yourscript :

 $ cat -v myscript ls -l myfile^M 

Se il tuo script non li possiede, i tuoi dati potrebbero – specialmente se stai leggendo da file ini / csv o curl :

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

Come li rimuovo?

Imposta il tuo editor per salvare il file con terminazioni di linea Unix, ovvero “terminatori di riga” o “caratteri di fine riga” e salvalo nuovamente.

Puoi anche rimuoverli da una riga di comando con dos2unix yourscript o cat yourscript | tr -d '\r' > fixedscript cat yourscript | tr -d '\r' > fixedscript .

Se trovato nei tuoi dati, puoi redirect la tua fonte attraverso tr -d '\r' :

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

Perché i ritorni a capo causano strani messaggi di errore?

Il carattere “carriage return”, ovvero CR o \r , fa sì che il cursore si sposti all’inizio della riga e continui a stampare da lì. In altre parole, inizia a sovrascrivere la riga dall’inizio. Questo è il motivo per cui si avvolgono in modo strano:

 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