%20%E3%82%92%E5%AF%BE%E8%A9%B1%E5%9E%8B%E3%82%B7%E3%82%A7%E3%83%AB%E3%81%A8%E5%90%8C%E3%81%98%E3%82%88%E3%81%86%E3%81%AB%E5%8B%95%E4%BD%9C%E3%81%95%E3%81%9B%E3%82%8B%E6%96%B9%E6%B3%95.png)
対話型 bash でこのコマンドを実行します。
$ timeout 1 sleep 2; echo $?
124
戻り値1241秒後、期待通り、timeout(1)に記載されている通りです。
ただし、同じものを cron ジョブとして実行したり、それを bash のコマンド文字列として指定した場合は、次のことは起こりません。
$ bash -c "timeout 1 sleep 2; echo $?"
0
bash 呼び出しに追加しても-i
役に立ちませんし、--foreground
timeout(1) のパラメータを使用しても役に立ちません。ksh と zsh でも同じことを試しましたが、常に同じ結果になったので、timeout(1) の動作に固有の問題であると思われます。
ネットで少し検索してみたところ、これはプロセス グループを介してシグナリングが進行する方法に関係している可能性があることがわかりましたが、非対話型の場合にタイムアウトを期待どおりに動作させる方法は見つかりませんでした。
それを実現する方法について何かヒントはありますか? 最終的に私が望んでいるのは、永久にブロックされる可能性のあるコマンドを cron で実行し、そのケースを確実に検出することです。
答え1
二重引用符のため、$?
展開されます前にbashコマンドが呼び出されます。これは、前のコマンド(最初のものexit $?
)
簡単なデモ
bash -c 'exit 42'
bash -c "timeout 1 sleep 2; echo $?" # => 42
解決策は一重引用符現在の対話型bashプロセスが変数を展開しないようにする
bash -c 'timeout 1 sleep 2; echo $?' # => 124
答え2
次のようにコマンドを実行してみてください:
bash -c "timeout 1 sleep 2"; echo $?