Come posso tracciare lo script che mi dà "comando non trovato" subito dopo il login?


8

Quando accedo, ho questi messaggi:

-bash: $'\r' : command not found
-bash: $'\r' : command not found
-bash: $'\r' : command not found 

È abbastanza chiaro che è causato dalle terminazioni di linea in stile Windows in alcuni script di avvio, quindi la mia domanda è: posso tenere traccia degli script che lo causano e come?


2
Prova a guardare i file .bashrc, .bash_profile e del profilo nella tua directory home così come / etc / profile
Raman Sailopal

Risposte:


14

Bash legge diversi file all'avvio, anche a seconda di come è stato avviato ( vedere il manuale per la descrizione ). Quindi ci sono cose del genere /etc/profile.d/che non vengono lette direttamente dalla shell, ma possono essere referenziate dagli altri file di avvio in molte distribuzioni.

Dovrai passare attraverso tutti questi, ma per fortuna, puoi solo grepper il ritorno in carrozza. Prova ad esempio qualcosa del tipo:

grep $'\r' ~/.bashrc ~/.profile ~/.bash_login ~/.bash_profile /etc/bash.bashrc /etc/profile /etc/profile.d/*

Vedi anche È possibile scoprire quali file stanno impostando / aggiungendo alle variabili di ambiente e il loro ordine di precedenza? per un problema simile.


6
Un altro posto dove cercare:~/.bash_aliases
Weijun Zhou,

1
Un'altra opzione è usare strace -e open your-shell, dalla risposta di Stéphane qui
Jeff Schaller

5

file (1) può essere utile anche qui.

$file *

signin:                                     Python script, ASCII text
signup:                                     Python script, ASCII text, with CRLF line terminators
site_off.htm:                               XML 1.0 document, ASCII text
sitemaps:                                   directory

Vedo che è signupnecessario rimuovere quelle fastidiose terminazioni di riga CRLF di Windows.

Per un ricorsivo direttamente come /home/usernameprobabilmente potresti combinare con finde xargs(e forse anche un grep):

$ find . | xargs file | grep CR

./foo_data/V: ASCII text, with CR, LF line terminators
./foo_data/Y: ASCII text, with CR, LF line terminators

3

Un altro metodo è quello di prendere tutti quegli script di avvio menzionati ed eco una stringa che identifica ognuno all'inizio di ognuno.

$ head .bashrc
echo "Running bashrc"

Quindi, al login, vedrai qualcosa del genere:

running bashrc
running bash_aliases
-bash: $'\r' : command not found
-bash: $'\r' : command not found
-bash: $'\r' : command not found 
running something_else

A quel punto puoi concludere che, (nell'esempio sopra) .bash_aliasescontiene le terminazioni di riga offensive.

Una volta identificato il file, ma le linee del problema non saltano fuori da te, puoi usare lo stesso metodo per rintracciare la linea. Eco un messaggio a metà del file, quindi 3 / 4s o 1 / 4s, a seconda dell'output. In questo modo puoi rintracciare la linea, a seconda che echi prima o dopo l'eco.


Sì, questo metodo è buono se si può automatizzare rapidamente, altrimenti è quasi lo stesso che guardare attraverso tutti questi file.
Denis Sablukov,

1
Tieni presente che potresti anche voler dire "fatto in esecuzione <file>" alla fine di ognuno. In questo caso non importa se solo alcune delle linee hanno terminazioni di riga CR, ma se stai cercando un altro errore potrebbe essere nel tuo .bashrc dopo aver sorgente .bash_aliases.
Ben Millwood,

1
Per qualcuno che sta solo imparando a eseguire il debug dei problemi della shell, o quando non è facile come cercare '\ r', QUESTA risposta vale la pena avere nella tua cassetta degli attrezzi della conoscenza. Ho ereditato un sistema di compilazione complesso che era il nido di un ratto di script intrecciati per eseguire build remote su SSH. Questo era l'unico modo per svolgerlo e spostarlo nei contenitori Docker.
Scott Prive

1
Un altro suggerimento generale: quando si tratta di script Bash correlati, tenere presente dove aggiungere le dichiarazioni di eco e (qualunque cosa si stia facendo) verificare frequentemente. Se uno script bash viene utilizzato per generare stringhe su STDOUT e hai aggiunto istruzioni di debug a STDOUT, probabilmente hai rotto la cosa che stavi eseguendo. A volte la risposta è utilizzare il comando "logger" per aggiungere informazioni / debug a uno script. Altre volte usa STDERR, se è una condizione di avvertimento.
Scott Prive,

@DenisSablukov se i tuoi file sono lunghi e guardando attraverso di loro richiede un po 'di tempo, questo metodo ti aiuterà a restringere la fonte più rapidamente. Non ci vuole molto tempo ad una riga all'inizio e alla fine di 6 file.
user394

3

Prendo la parte difficile di questa domanda per non essere "come posso trovare i ritorni a capo in un file?" ma "come posso sapere quali file utilizza il mio bashrc?"

Per la seconda domanda, puoi provare qualcosa del genere:

bash -x .bashrc

Questo ti mostrerà tutto ciò che fa la tua bashrc, inclusi tutti i file a cui fa riferimento. È rumoroso, ma dovrebbe aiutarti a rintracciare quali file vengono utilizzati.

Tranne il fatto, i miei (e molti altri) .bashrcfile escono presto se non vengono eseguiti in modo interattivo, quindi devi indurlo a superare quel controllo:

bash -ix .bashrc

Qui la -imodalità interattiva delle forze.

Per estrarre solo i casi in cui si fonte un file, qualcosa del genere funziona per me, ma non posso promettere che la regex cattura tutto:

bash -ix .bashrc 2> >(grep -E '^\+* (\.|source)')

Suppongo che potresti volere anche i messaggi di errore, quindi qualcosa del tipo:

bash -ix .bashrc 2> >(grep -E -e '^\+* (\.|source)' -e 'command not found')

Se per qualche ragione nulla di tutto ciò dovesse funzionare, ricorrerei a strace -e open bashqualcosa del genere, per trovare ogni volta che un file viene aperto dalla tua sessione bash. Ma questa è una soluzione ancora più pesante / rumorosa.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.