Como posso rastrear um script que me dê “comando não encontrado” logo após o login?


8

Ao fazer login, tenho estas mensagens:

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

É bastante claro que isso é causado por terminações de linha no estilo do Windows em alguns scripts de inicialização. Portanto, minha pergunta é: Posso rastrear scripts que causam isso e como?


2
Tente olhar para os arquivos .bashrc, .bash_profile e perfil em seu diretório pessoal, bem como / etc / profile
Raman Sailopal

Respostas:


14

O Bash lê vários arquivos diferentes na inicialização, mesmo dependendo de como foi iniciado ( consulte o manual para obter a descrição ). Depois, há coisas assim /etc/profile.d/que não são lidas diretamente pelo shell, mas podem ser referenciadas a partir de outros arquivos de inicialização em muitas distribuições.

Você terá que passar por tudo isso, mas, felizmente, é possível apenas greppelo retorno de carro. Tente, por exemplo, algo como:

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

Consulte também É possível descobrir quais arquivos estão configurando / adicionando às variáveis ​​de ambiente e sua ordem de precedência? para um problema semelhante.


6
Mais um lugar para procurar:~/.bash_aliases
Weijun Zhou

11
Outra opção é usar strace -e open your-shell, a partir da resposta
Jeff Schaller

5

O arquivo (1) também pode ser útil aqui.

$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

Percebo que é signupnecessário remover essas terminações de linha CRLF do Windows.

Para um recursivo diretamente como /home/usernamevocê provavelmente poderia combinar com finde xargs(e talvez um grep também):

$ 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

Outro método é pegar todos os scripts de inicialização mencionados e repetir uma string identificando cada um no início de cada um.

$ head .bashrc
echo "Running bashrc"

Então, no login, você verá algo assim:

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

Nesse ponto, você pode concluir que (no exemplo acima) .bash_aliasescontém as terminações da linha incorreta.

Depois de identificar o arquivo, mas as linhas do problema não surgem, você pode usar o mesmo método para rastrear a linha. Faça eco de uma mensagem na metade do arquivo e depois em 3/4 ou 1/4, dependendo da saída. Dessa forma, você pode rastrear a linha, dependendo de ela ecoar antes ou depois do seu eco.


Sim, esse método é bom se você pode automatizá-lo rapidamente, caso contrário, é quase o mesmo que procurar em todos esses arquivos.
Denis Sablukov 15/03/19

11
Observe que você também pode querer dizer 'concluído a execução de <arquivo>' no final de cada um. Nesse caso, isso realmente não importa, a menos que apenas algumas das linhas tenham terminações de linha CR, mas se você estiver procurando por outro erro, ele poderá estar no seu .bashrc após a origem de .bash_aliases.
Ben Millwood

11
Para alguém que está apenas aprendendo a depurar problemas de shell ou quando não é tão fácil quanto pesquisar por \ \, vale a pena ter ESTA resposta na sua caixa de ferramentas de conhecimento. Eu herdei um sistema complexo de compilação, que era um ninho de scripts entrelaçados para fazer compilações remotas sobre SSH. Essa era a única maneira de desenrolá-lo e movê-lo para contêineres do Docker.
21419 Scott Scive -

11
Outra dica geral - ao lidar com scripts Bash inter-relacionados, lembre-se de onde você adiciona instruções de eco e (o que quer que esteja fazendo) testa com frequência. Se um script bash for usado para gerar seqüências de caracteres para STDOUT e você adicionar instruções de depuração ao STDOUT, provavelmente você quebrou a coisa que estava depurando. Às vezes, a resposta é empregar o comando "logger" para adicionar informações / depuração a um script. Outras vezes, use STDERR, se for uma condição de aviso.
Scott Prive

@DenisSablukov, se seus arquivos forem longos, e analisá-los leva um tempo, esse método ajudará você a restringir a fonte mais rapidamente. Não leva muito tempo para uma linha na parte superior e inferior de 6 arquivos.
user394

3

Considero que a parte mais difícil desta pergunta não é "como posso encontrar retornos de carro em um arquivo?" mas "como posso descobrir quais arquivos meu bashrc usa?"

Para a segunda pergunta, você pode tentar algo como isto:

bash -x .bashrc

Isso mostrará tudo o que o seu bashrc faz, incluindo todos os arquivos a que se refere. É barulhento, mas deve ajudá-lo a rastrear quais arquivos estão sendo usados.

Exceto, de fato, meus .bashrcarquivos (e muitos outros) saem mais cedo, se não forem executados de maneira interativa; portanto, você deve enganá-lo para passar nessa verificação:

bash -ix .bashrc

Aqui o -imodo interativo de forças.

Para destacar apenas os casos em que você cria um arquivo, algo assim funciona para mim, mas não posso prometer que o regex captura tudo:

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

Eu acho que você também pode querer as mensagens de erro, então algo como:

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

Se, por algum motivo, nada disso funcionasse, eu recorreria a strace -e open bashalgo assim, para descobrir sempre que qualquer arquivo for aberto por sua sessão do bash. Mas essa é uma solução ainda mais pesada / barulhenta.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.