bash ファイル内の bash "script" コマンド?

bash ファイル内の bash "script" コマンド?

/usr/bin/local/myscript という bash スクリプトがあります。このファイルを通常は外部ソフトウェア (私の場合は Autohotkey) から実行します。基本的に、スクリプトはすぐに終了し、ウィンドウが閉じられるため、ウィンドウにログ、情報ログ、エラー ログは表示されません。プログラムがうまく動作しなかった場合は、デバッグのために実行手順全体を「スクリプト化」するのが好きです。しかし、ファイルscript ~/script.txtの先頭に を入れるだけでmyscriptはうまくいきませんでした。何が起こっているのかわかりません。ファイルの次の行は基本的に実行されませんでした。では、bash ファイルで「スクリプト」を使用する (適切な) 方法、または「スクリプト」のより良い代替手段はありますか?

答え1

script ~/script.txtしかし、ファイルの先頭に を置くだけではmyscript機能しませんでした。何が起こっているのかわかりません。ファイルの次の行は基本的に実行されませんでした。

を解釈するシェルにとってmyscriptscript ~/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

  1. スクリプトのstderrをログファイルにリダイレクトします。これはスクリプト内から次のように実行できます。

    # just after shebang
    exec 2>/path/to/logfile
    

    stdout に重要な出力が生成され、それが実際にどこかに送られる場合myscript(パイプまたはリダイレクト経由)、これを壊したくはありません。ただし、通常はターミナルに出力され、これもログに記録したい場合は、stderr と stdout の両方をログファイルにリダイレクトします。

    # just after shebang
    exec 2>/path/to/logfile 1>&2
    

    myscriptこの方法は、ターミナルなしで実行した場合でも機能します。

  2. bashあるいは、スクリプトの最後に対話型シェル (例 ) を実行させます。新しいシェルはウィンドウが閉じないようにし、スクリプトがこれまでにターミナルに出力した内容を確認できます。これには当然ターミナルが必要です。が または自体、あるいは別の実行可能ファイルmyscriptに発生した場合、 の行に到達することはありません。この点を考慮してください。exitkillexecbash

    何らかの理由で、bashスクリプトから開始された対話型処理によって端末がクリアされるなどした場合は、sleep 3600代わりに を使用します。ポイントは、追加のシェルは実際には必要なく、前の出力を調べることができるように端末エミュレータを開いたままにするプロセスが必要であるということです。

どちらの方法を選択する場合でも、

set -x

早い段階でmyscript、シェルがそれを解釈して、実行時にコマンドと引数を印刷するようにします。これにより、役立つ情報が得られるはずです。

関連情報