
/usr/bin/local/myscript という bash スクリプトがあります。このファイルを通常は外部ソフトウェア (私の場合は Autohotkey) から実行します。基本的に、スクリプトはすぐに終了し、ウィンドウが閉じられるため、ウィンドウにログ、情報ログ、エラー ログは表示されません。プログラムがうまく動作しなかった場合は、デバッグのために実行手順全体を「スクリプト化」するのが好きです。しかし、ファイルscript ~/script.txt
の先頭に を入れるだけでmyscript
はうまくいきませんでした。何が起こっているのかわかりません。ファイルの次の行は基本的に実行されませんでした。では、bash ファイルで「スクリプト」を使用する (適切な) 方法、または「スクリプト」のより良い代替手段はありますか?
答え1
script ~/script.txt
しかし、ファイルの先頭に を置くだけではmyscript
機能しませんでした。何が起こっているのかわかりません。ファイルの次の行は基本的に実行されませんでした。
を解釈するシェルにとってmyscript
、script ~/script.txt
は外部の実行可能ファイルを実行する単なるコマンドです。script
この場合、実行可能ファイルは です。
実行ファイルがsleep
、 、tar
または の場合ls
、シェルは の残りを解釈する前に、実行ファイルが完了するまで待機することが予想されますmyscript
。 の場合script
も違いはありません。シェルはscript
が完了するまで待機します。
script
は対話型の使用を目的としています。 は、script ~/script.txt
を解釈するシェルではない対話型シェルを実行しますmyscript
。 がない場合、「ウィンドウが閉じる」と書かれているscript
ので、ウィンドウを表示するターミナル エミュレーターで が実行されると想定しますmyscript
。 そうであれば、 の場合、script
おそらく によって開始されたこの内部シェルを確認しscript
、外部シェルが待機している間に対話することができました。 は、script
内部シェルで行った操作をログに記録します。 内部シェルを終了すると終了しscript
、その後でのみ外部シェル (つまりmyscript
) が続行されます。 ただし、ターミナル エミュレーターを閉じた可能性があり、外部シェルは SIGHUP を受け取り、続行されませんでした。
これは重要ではありません。外側のシェルが継続している場合でも、script
内部から呼び出されてもmyscript
デバッグには役立たないことが明らかになっているためです。myscript
デバッグには少なくとも 2 つの方法がありますmyscript
。
スクリプトのstderrをログファイルにリダイレクトします。これはスクリプト内から次のように実行できます。
# just after shebang exec 2>/path/to/logfile
stdout に重要な出力が生成され、それが実際にどこかに送られる場合
myscript
(パイプまたはリダイレクト経由)、これを壊したくはありません。ただし、通常はターミナルに出力され、これもログに記録したい場合は、stderr と stdout の両方をログファイルにリダイレクトします。# just after shebang exec 2>/path/to/logfile 1>&2
myscript
この方法は、ターミナルなしで実行した場合でも機能します。bash
あるいは、スクリプトの最後に対話型シェル (例 ) を実行させます。新しいシェルはウィンドウが閉じないようにし、スクリプトがこれまでにターミナルに出力した内容を確認できます。これには当然ターミナルが必要です。が または自体、あるいは別の実行可能ファイルmyscript
に発生した場合、 の行に到達することはありません。この点を考慮してください。exit
kill
exec
bash
何らかの理由で、
bash
スクリプトから開始された対話型処理によって端末がクリアされるなどした場合は、sleep 3600
代わりに を使用します。ポイントは、追加のシェルは実際には必要なく、前の出力を調べることができるように端末エミュレータを開いたままにするプロセスが必要であるということです。
どちらの方法を選択する場合でも、
set -x
早い段階でmyscript
、シェルがそれを解釈して、実行時にコマンドと引数を印刷するようにします。これにより、役立つ情報が得られるはずです。