¿Cómo puedo rastrear el script que me da "comando no encontrado" justo después del inicio de sesión?

8

Cuando inicio sesión, tengo estos mensajes:

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

Está bastante claro que es causado por las terminaciones de línea al estilo de Windows en algunos scripts de inicio, por lo que mi pregunta es: ¿Puedo rastrear el script que causa eso y cómo?

Denis Sablukov
fuente
2
Intente mirar los archivos .bashrc, .bash_profile y profile en su directorio personal, así como / etc / profile
Raman Sailopal

Respuestas:

14

Bash lee varios archivos diferentes al inicio, incluso dependiendo de cómo se inicie ( consulte el manual para ver la descripción ). Luego, hay cosas como esas /etc/profile.d/que el shell no lee directamente, pero se puede hacer referencia a ellas desde los otros archivos de inicio en muchas distribuciones.

Tendrá que pasar por todo eso, pero afortunadamente, puede hacerlo solo greppara el retorno del carro. Pruebe, por ejemplo, algo como:

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

Consulte también ¿Es posible averiguar qué archivos están configurando / agregando a las variables de entorno y su orden de precedencia? por un problema similar

ilkkachu
fuente
66
Un lugar más para buscar:~/.bash_aliases
Weijun Zhou
1
Otra opción es usar strace -e open your-shell, de la respuesta
Jeff Schaller
5

El archivo (1) también puede ser útil aquí.

$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

Puedo ver que signupnecesita eliminar esas molestas terminaciones de línea CRLF de Windows.

Para un recursivo directamente como /home/usernameprobablemente podría combinar con findy xargs(y tal vez un grep, también):

$ 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
Kevin_Kinsey
fuente
3

Otro método es tomar todos los scripts de inicio mencionados y hacer eco de una cadena que identifica cada uno al comienzo de cada uno.

$ head .bashrc
echo "Running bashrc"

Luego, al iniciar sesión, verá algo como esto:

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

En ese punto, puede concluir que (en el ejemplo anterior) .bash_aliasescontiene las terminaciones de las líneas ofensivas.

Una vez que haya identificado el archivo, pero las líneas problemáticas no saltan a la vista, puede usar el mismo método para rastrear la línea. Haga eco de un mensaje a la mitad del archivo, luego 3/4 o 1/4, dependiendo de la salida. De esa manera puede rastrear la línea, dependiendo de si hace eco antes o después de su eco.

usuario394
fuente
Sí, este método es bueno si uno puede automatizarlo rápidamente, de lo contrario es casi lo mismo que mirar a través de todos estos archivos.
Denis Sablukov
1
Tenga en cuenta que es posible que también desee decir 'listo ejecutando <archivo>' al final de cada uno. En este caso, realmente no importa a menos que solo algunas de las líneas tengan terminaciones de línea CR, pero si está buscando otro error, podría estar en su .bashrc después de obtener .bash_aliases.
Ben Millwood
1
Para alguien que está aprendiendo a depurar problemas de shell, o cuando no es tan fácil como buscar '\ r', vale la pena tener ESTA respuesta en su caja de herramientas de conocimiento. Heredé un complejo sistema de compilación que era un nido de ratas de scripts entrelazados para hacer compilaciones remotas sobre SSH. Esta era la única forma de desenrollarlo y moverlo a los contenedores Docker.
Scott Prive
1
Otro consejo general: cuando trabaje con scripts de Bash interrelacionados, tenga en cuenta dónde agrega declaraciones de eco y (lo que sea que esté haciendo) realice pruebas con frecuencia. Si se usa un script bash para generar cadenas en STDOUT y agregó declaraciones de depuración a STDOUT, entonces probablemente rompió lo que estaba depurando. A veces, la respuesta es emplear el comando "registrador" para agregar información / depuración a un script. Otras veces use STDERR, si es una condición de advertencia.
Scott Prive
@DenisSablukov si sus archivos son largos, y revisarlos lleva un tiempo, este método lo ayudará a reducir la fuente más rápidamente. No toma mucho tiempo en una línea a la parte superior e inferior de 6 archivos.
user394
3

Considero que la parte difícil de esta pregunta no es "¿cómo puedo encontrar retornos de carro en un archivo?" pero "¿cómo puedo averiguar qué archivos usa mi bashrc?"

Para la segunda pregunta, puede intentar algo como esto:

bash -x .bashrc

Esto le mostrará todo lo que hace su bashrc, incluidos todos los archivos a los que se refiere. Es ruidoso, pero debería ayudarlo a localizar qué archivos se están utilizando.

Excepto, de hecho, mis (y muchos otros) .bashrcarchivos salen temprano si no se ejecutan de manera interactiva, por lo que debe engañarlo para que pase esa verificación:

bash -ix .bashrc

Aquí las -ifuerzas de modo interactivo.

Para resolver solo los casos en los que obtiene un archivo, algo como esto funciona para mí, pero no puedo prometer que la expresión regular atrapa todo:

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

Supongo que también puede querer los mensajes de error, así que algo como:

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

Si por alguna razón nada de esto funcionara, recurriría a strace -e open bashalgo así, para encontrar cada vez que su sesión de bash abra algún archivo. Pero esa es una solución aún más pesada / ruidosa.

Ben Millwood
fuente