Bash の詳細な実行

検索でこのページを見つけた場合は、おそらく bash の実行に関する何らかの問題を解決しようとしていると思われます。

おそらく、bash 環境で環境変数が設定されておらず、その理由がわからないのでしょう。 機能するまで、さまざまな bash ブート ファイルやプロファイル、あるいはすべてのファイルに何かをランダムに貼り付けていた可能性があります。

いずれにしても、このメモの目的は、問題に対処できるように、bash を起動する手順をできるだけ簡単に説明することです。

Диаграмма

このフローチャートは、bash 実行時のすべてのプロセスを要約しています。

Bash の詳細な実行

それでは各部分を詳しく見ていきましょう。

ログインシェル?

まず、ログイン シェルを使用しているかどうかを選択する必要があります。

ログイン シェルは、対話型セッションにログインするときに最初に入力するシェルです。 ログイン シェルにはユーザー名とパスワードは必要ありません。 フラグを追加することでログインシェルを強制的に起動できます --login 呼ばれたとき bashたとえば、次のようになります。

bash --ログイン

最初に bash シェルを起動すると、ログイン シェルによって基本環境がセットアップされます。

相互の作用?

次に、シェルが対話型かどうかを判断します。

これは変数の存在によって確認できます。 PS1 (コマンド入力機能をインストールします):

if [ "${PS1-}" ]; then インタラクティブをエコーする else 非インタラクティブな fi をエコーする

または、オプションが設定されているかどうかを確認してください -i、特殊なハイフン変数を使用 - bash では、たとえば次のようになります。

$エコー$-

出力にシンボルがある場合 iの場合、シェルは対話型になります。

ログインシェル内で?

ログインシェルを使用している場合、bash はファイルを検索します。 /etc/profile 存在する場合は実行されます。

次に、これら XNUMX つのファイルのいずれかを次の順序で検索します。

~/.bash_profile ~/.bash_login ~/.profile

XNUMX つが見つかると、それを開始し、他のものはスキップします。

インタラクティブシェルで?

非ログイン シェルにいる場合は、すでにログイン シェルに入っているものとみなされ、環境が設定され、継承されます。

この場合、次の XNUMX つのファイルが存在する場合、それらのファイルが順番に実行されます。

/etc/bash.bashrc ~/.bashrc

オプションはありませんか?

ログイン シェルまたは対話型シェルのいずれにもいない場合、環境は実際には空になります。 これは多くの混乱を引き起こします (cron ジョブについては以下を参照)。

この場合、bash は変数を調べます。 BASH_ENV 環境を変更し、そこで指定された対応するファイルを作成します。

よくある困難と経験則

cronジョブ

bash の起動をデバッグするときの 95% は、cron ジョブが期待どおりに実行されていないことが原因です。

このいまいましい任務 コマンドラインで実行すると正常に動作しますが、crontabで実行すると失敗します.

それは XNUMXつの理由:

  • Cron ジョブは対話型ではありません。
  • コマンド ライン スクリプトとは異なり、cron ジョブはシェル環境を継承しません。

環境は対話型シェルを継承するため、通常、シェル スクリプトが対話型ではないことに気付かず、気にすることもありません。 つまり、すべてが PATH и alias 予想どおりに構成されました。

このため、多くの場合、特定の値を設定する必要があります。 PATH ここのような cron タスクの場合:

* * * * * PATH=${PATH}:/path/to/my/program/folder myprogram

相互に呼び出しを行うスクリプト

もう XNUMX つの一般的な問題は、スクリプトが相互に呼び出すように誤って設定されている場合です。 例えば、 /etc/profile に訴える ~/.bashrc.

これは通常、誰かが何らかのエラーを修正しようとして、すべてがうまくいったように見えるときに発生します。 残念ながら、これらの異なるタイプのセッションを分離する必要がある場合、新たな問題が発生します。

サンドボックス化された Docker イメージ

シェルの実行を実験するために、安全な環境でシェルの実行をデバッグするために使用できる Docker イメージを作成しました。

実行:

$ docker run -n bs -d imiell/bash_startup
$ docker exec -ti bs bash

Dockerfile が配置されています ここで.

強制的にログインしてログイン シェルをシミュレートするには:

$ bash --login

変数のセットをテストするには BASH_ENV:

$ env | grep BASH_ENV

デバッグ用 crontab 単純なスクリプトが XNUMX 分ごとに実行されます ( /root/ascript):

$ crontab -l
$ cat /var/log/script.log

出所: habr.com

コメントを追加します