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


8

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

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

一部の起動スクリプトのWindowsスタイルの行末が原因であることが明らかであるため、私の質問は、それを引き起こすスクリプトを追跡できますか?


2
ホームディレクトリの.bashrc、.bash_profile、プロファイルファイル、および/ etc / profileを確認してみてください
Raman Sailopal

回答:


14

Bashは、起動方法にもよりますが、起動時にさまざまなファイルを読み取ります(説明については、マニュアルを参照してください)。次に/etc/profile.d/、シェルによって直接読み取られないようなものがありますが、多くのディストリビューションの他のスタートアップファイルから参照できます。

あなたはそれらすべてを通過する必要がありますが、幸運にも、grepキャリッジリターンのためだけにできます。たとえば次のようなものを試してください:

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

参照どのファイルが環境変数に設定/追加されているか、およびそれらの優先順位を見つけることは可能ですか?同様の問題のため。


6
検索するもう1つの場所:~/.bash_aliases
Weijun Zhou

1
もう1つのオプションはstrace -e open your-shellステファンの答え
ジェフシャラー

5

ここでも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の行末を削除する必要があることがわかります。

/home/usernameあなたがおそらく再結合するような場合、おそらくfindand xargs(そしておそらく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

もう1つの方法は、前述の起動スクリプトをすべて取得し、それぞれの開始時にそれぞれを識別する文字列をエコーすることです。

$ 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までエコーします。こうすることで、エコーの前か後かによって、ラインを追跡できます。


ええ、この方法は、迅速に自動化できる場合は適切ですが、それ以外の場合は、これらすべてのファイルを調べるのとほとんど同じです。
Denis Sablukov

1
それぞれの終わりに「done running <file>」と言うこともできます。この場合、一部の行だけにCRの行末がある場合を除いて、それは実際には重要ではありませんが、別のエラーを探している場合は、.bash_aliasesをソースした後に.bashrcにある可能性があります。
ベンミルウッド

1
シェルの問題をデバッグすることを学ぶだけの人、または「\ r」を検索するほど簡単ではない場合、この答えはナレッジツールボックスに入れておく価値があります。私は、SSH経由でリモートビルドを行うために絡み合ったスクリプトのネズミの巣である複雑なビルドシステムを継承しました。これは、それを巻き戻してDockerコンテナーに移動する唯一の方法でした。
Scott Prive

1
もう1つの一般的なヒント-相互に関連するBashスクリプトを扱う場合は、echoステートメントを追加する場所に注意し、(何を実行している場合でも)頻繁にテストしてください。文字列をSTDOUTに出力するためにbashスクリプトが使用されており、STDOUTにデバッグ文を追加した場合は、デバッグしていたものを壊した可能性があります。時々、答えは「ロガー」コマンドを使用してスクリプトに情報/デバッグを追加することです。警告状態の場合は、STDERRを使用することもあります。
Scott Prive

@DenisSablukovあなたのファイルが長く、それらを調べるのに時間がかかる場合、この方法はソースをより早く絞り込むのに役立ちます。6つのファイルの最上部と最下部まで一列に並ぶのに、それほど長い時間はかかりません。
user394

3

この質問の難しい部分は、「ファイル内の改行を見つけるにはどうすればよいですか」ではないと思います。しかし、「自分のbashrcが使用するファイルを見つけるにはどうすればよいですか?」

2番目の質問については、次のようなことを試すことができます。

bash -x .bashrc

これにより、bashrcが参照するすべてのファイルを含め、bashrcが行うすべてのことが表示されます。うるさいですが、使用されているファイルを追跡するのに役立ちます。

実際には、私の.bashrcファイル(および他の多くのファイル)は、インタラクティブに実行されない場合は早期に終了するため、それをだましてそのチェックに合格させる必要があります。

bash -ix .bashrc

ここでは、-iインタラクティブモードを強制します。

あなたがファイルをソースするケースだけをgrepするために、このようなものは私にとってはうまくいきますが、正規表現がすべてをキャッチするとは約束できません:

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

エラーメッセージが必要になることもあるので、次のようにします。

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

なんらかの理由でこれが機能しない場合はstrace -e open bash、bashセッションによってファイルが開かれるたびに見つけるために、またはそれに似た方法を使用します。しかし、それはさらに重い/ノイズの多いソリューションです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.