ログイン後すぐに「コマンドが見つかりません」と表示されるスクリプトを追跡するにはどうすればよいですか?

ログイン後すぐに「コマンドが見つかりません」と表示されるスクリプトを追跡するにはどうすればよいですか?

ログインすると、次のメッセージが表示されます。

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

明らかに、これはいくつかの起動スクリプトのWindowsスタイルの行の終わりが原因で発生するので、私の質問は次のようになります。どのスクリプトが問題を引き起こしているのか、どのように追跡できますか?

答え1

Bashは起動方法に応じて起動時にさまざまなファイルを読み取ります(ドキュメントの説明を参照してください)。/etc/profile.d/シェルから直接読み取ることはありませんが、多くのディストリビューションの他の起動ファイルで参照できる同様の内容があります。

これをすべて行う必要がありますが、幸いにもgrepEnterキーを押すだけです。たとえば、次のようになります。

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

また、見ることができます環境変数にどのファイルが設定/追加されるか、優先順位がわかりますか?同様の質問については。

答え2

file(1) もここで役に立ちます。

$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

signup迷惑なWindows CRLF行末を削除する必要性がわかります。

直接再帰の場合は、and(およびgrep)と組み合わせること/home/usernameができます。findxargs

$ 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

別のアプローチは、上記のすべての起動スクリプトを取得し、各スクリプトの先頭に各スクリプトを識別する文字列を表示することです。

$ head .bashrc
echo "Running bashrc"

そしてログインをすると次のような内容が出ます。

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

この時点で、上記の例では.bash_aliases問題のある行末が含まれていると結論付けることができます。

ファイルを識別しても問題行が表示されない場合は、同じ方法を使用してその行を追跡できます。メッセージをファイルにエコーし、出力に応じて3/4秒または1/4秒後にエコーします。これにより、エコーの前または後にエコーされるかどうかに基づいて線を追跡できます。

答え4

この質問の難しい部分は、「ファイル内のキャリッジリターンをどのように見つけるのですか?」ではなく、「私のbashrcが使用するファイルをどのように見つけるのですか?」と思います。

2番目の質問では、次のように試してみることができます。

bash -x .bashrc

これはあなたに見せるでしょうすべて参照するすべてのファイルを含むbashrcによって実行されます。騒々しいが、どのファイルが使用されているかを追跡するのに役立ちます。

ただし、実際には、.bashrc私のファイル(および他の多くの)ファイルはインタラクティブに実行されていないと早く終了するので、そのチェックに合格するようにだまされなければなりません。

bash -ix .bashrc

-i病歴対話モードです。

ソースファイルだけを見つけるには、次の方法が私にとって効果的でしたが、正規表現がすべてをキャプチャすることを保証することはできません。

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

次のエラーメッセージが必要な場合があると思います。

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

何らかの理由でこれらのいずれかが機能しない場合は、strace -e open bashbashセッションがファイルを開くたびにこの方法を使用して検索します。しかし、これはより重くて騒々しい解決策です。

関連情報