問題タブ [bash-trap]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
2 に答える
763 参照

bash - 一時ファイルなしでトラップを復元する

引数を指定しないtrapと、すべてのトラップに対して現在設定されているコマンドが出力されます。ただし、サブシェルはトラップを継承しないため、トラップを保存および復元する標準的な例は bash で失敗します。

割り当ての RHS のトラップはサブシェルで実行されるため、save_traps は常に空の文字列です。の出力を一時ファイルに書き込む以外trapに、トラップに設定されている現在のコマンドをスクリプトで見つけるにはどうすればよいでしょうか?

0 投票する
5 に答える
4944 参照

linux - rsync /subshel​​lexecステートメント中に割り込みをトラップしないBash

コンテクスト:

EXIT疑似信号のサブシェルとトラップを含むbashスクリプトがありますが、。の間に割り込みを適切にトラップしていませんrsync。次に例を示します。

スクリプトの考え方は次のとおりです。重要なロジックのほとんどは、ログファイルを介してログファイルにパイプされるサブシェルで実行されるため、すべてをログに記録するためにメインロジックのすべての行teeを実行する必要はありません。teeサブシェルが終了するか、何らかの理由でスクリプトが停止すると(EXIT疑似信号はこれらすべてのケースをキャプチャする必要があります)、トラップはそれをインターセプトしてcleanup()関数を実行し、トラップを削除します。rsyncandsleepコマンド(スリープは単なる例です)は、実行中に親スクリプトを強制終了した場合にゾンビプロセスが作成されないようにするために実行されます。またexec、実行時間が長くなる可能性のある各コマンドは、独自のサブシェルにラップされます。exec終了すると、スクリプト全体が終了することはありません。

問題:

killexec / subshel​​lwrappedコマンドの実行中に(またはCTRL + Cを介して)スクリプトを中断するsleepと、トラップが正しく機能し、「クリーンアップ!」と表示されます。エコーしてログに記録しました。rsyncコマンド中にスクリプトを中断するrsyncと、endが表示され、画面に書き込みrsync error: received SIGINT, SIGTERM, or SIGHUP (code 20) at rsync.c(544) [sender=3.0.6]ます。その後、スクリプトは終了します。クリーンアップもトラッピングもありません。なぜ中断/殺害はrsyncトラップをトリガーしないのですか?

rsyncでスイッチを使用してみました--no-detachが、何も変わりませんでした。私はbash4.1.2、rsync 3.0.6、centOS6.2を持っています。

0 投票する
1 に答える
1437 参照

bash - bash スクリプトでの同時ロギング

私は現在、シェルスクリプトが時々同時ロギングで失敗する理由を理解しようとしています。

次のようなシェル関数があります。

時々、これは構文エラーで失敗します:

問題は、複数のサブプロセスがあり、それぞれがログを記録したり、トラップを送信したりすることです (その間、ログも実行されます)。問題をデバッグしたところ、関数が同時に 3 回入力されたときにこれが発生することがわかりました。最初にmainプロセスに入り、次にchild. のdate部分l_textが実行された後、mainget は a によって中断され、これtrapは何かをログに記録しようとします。と はログを正常に終了しますが、トラップの後に再開され、(おそらく) その部分を実行しようとすると、このエラーで失敗します。childtrapchildtrapmainhostname

そのため、ログステートメントmainの一部を生成している間にスリープ状態になるのが好きではないようで$(date +'%Y-%m-%d %H:%M:%S') $(hostname -s) ${l_text}、うまく再開できません。私はローカル変数とスレッドセーフな出力方法を使用しているだけなので、これはうまくいくはずだと思っていました。

これは、私がここで遭遇している一般的な同時実行の問題ですか? それとも、これは bash スクリプトのトラップ メカニズムに固有のものですか? 私は C での SIGNAL 処理の商品について知っているので、SIGNAL ハンドラーでは特定の操作しか許可されていないことを認識しています。ただし、bash スクリプトで SIGNAL を処理するときにも同じ予防措置が適用されるかどうかはわかりません。これに関するドキュメントを見つけようとしましたが、スクリプトでの SIGNAL 処理に関する問題を示すドキュメントは見つかりませんでした。

編集

問題を再現するために使用できる実際の単純なスクリプトを次に示します。

5 行echo $text >> /dev/null目の構文エラーが原因で、このスクリプトが強制終了されることがあります。 1 つずつエラーもあり、実際のエラーは 4 行目にありますlocal text="$(date +'%Y-%m-%d %H:%M:%S') $(hostname -s) $1"

上記のスクリプトを修正するために何をすべきか知っている人はいますか? 私はすでに文字列の構築をいくつかの一時変数に移動しようとしました:

この方法では、エラーの発生頻度は低くなりますが、それでも存在するため、これは実際の修正ではありません。

0 投票する
1 に答える
4697 参照

bash - この単純な bash トラップが失敗するのはなぜですか

私はまだ bash スクリプトにかなり慣れていないため、この単純なトラップが期待どおりに機能しない理由を理解するのに苦労しています。

目標CTRL- +を押してスキップできるオプションの待機期間を作成しますC

CTRL+ -を押したときの期待される結果Cすぐに「昼寝する時間がありません!」と反響します。そして終了します。

CTRL+ -を押した実際の結果は、Cすぐに "naptime over" をエコーし​​ます。そして終了します。

トラップ関数が呼び出されないのはなぜですか?

0 投票する
2 に答える
779 参照

bash - Bash:エラーの理由をトラップする方法は?

シェル スクリプト内でエラーをトラップし、エラーの理由に関するレポートを生成したいと考えています。

私のerror_handler機能では、シグナルがキャッチされた理由を示したいと思いますERR(たとえば、「許可が拒否されました」、「リモートホストが見つかりません」など)。

これは可能ですか?

0 投票する
1 に答える
2276 参照

linux - Bash スクリプト: SIGTSTP を適切に処理できません

デバイスをマウントおよびアンマウントするbashスクリプトがあり、その間にいくつかの読み取り操作を実行します。デバイスは非常に遅いため、スクリプトが完了するまでに約 15 秒かかります (マウントには少なくとも 5 ~ 6 秒かかります)。このデバイスをマウントしたままにしておくと他の問題が発生する可能性があるため、このスクリプトを中断させたくありません。

そうは言っても、SIGINT(Ctrl + c)を正しく処理できますが、SIGTSTP(Ctrl + z)を処理しようとすると、スクリプトがフリーズします。つまり、シグナルはトラップされますが、ハンドラーは実行されません。

プロセスに手動で KILL シグナルを送信する必要があります。なぜこれが起こっているのか、どうすれば修正できるのでしょうか?

0 投票する
2 に答える
3134 参照

bash - ifステートメント内にエラーをトラップする方法

次のコードを実行します。


次の出力を生成します。


ifステートメント内にも「コマンドが見つかりません」エラー をトラップするにはどうすればよいですか?

0 投票する
2 に答える
1692 参照

bash - ゼロ以外の値を返す関数を実行するときに、元の呼び出し元の lineno を取得する方法

以下を含むソースになる func.sh スクリプトを作成しました。

次に、main.sh スクリプトを作成しました。

私の目標は、戻り値を正しく管理していないlineno 4 (上記のスクリプト) をキャッチすることです。

そのために私は試しました:

ここでlineno 23をキャッチしたいと思います。
出力は次のとおりです。

正しい lineno は、関数自体の内部で呼び出し元によって検出されますが、トラップでは検出されません。スクリプトの名前は正しい (main.sh) が、lineno ではありません (22 ではなく 1????)

私も試しました

しかし、出力は次のとおりです。

関数自体の内部の呼び出し元はまだ正しいlineno (この場合は 21) を検出していますが、トラップ内の状況はさらに最悪です。これは、 return 1 がある func.sh 内の行である lineno 8 を取得しているためです ... (トラップ内の呼び出し元が行を間違ったスクリプト main.sh に参照している間)。

この時点でアイデアが尽きた…

0 投票する
1 に答える
1686 参照

bash - ソースファイルはどのようにしてトラップDEBUGを継承できますか?

次のスニペットを実行します。


ここで、source.shは


与える:


これは、ソースファイル内のすべてのコマンドがDEBUGトラップによってトラップされないことを意味します。
実際、行を追加すると

2行目のsource.sh内では、すべてが希望どおりに機能します(ソースファイル内のコマンドもトラップされます)。

ソースを作成する必要のあるファイルに対して上記の行が繰り返されないようにするには、これをデフォルトの動作にするにはどうすればよいですか?言い換えると、ソースファイルにDEBUGトラップを継承するように指示する機会はありますか?

0 投票する
1 に答える
3653 参照

bash - bash メールでエラーを送信

バックアップ ジョブを実行する bash スクリプトを作成しました。エラーを見逃さないように、スクリプトを errexit と pipefail で実行します。私が今欲しいのは、エラーが発生した場合にメールを送信するスクリプトです。私はこれを機能させました。しかし、スクリプト エラーを電子メール本文に含めたいと思います。これどうやってするの?

ここにスクリプトがあります:

助けてくれてどうもありがとう!