文字列をrofiにパイプするbashスクリプトを作成しようとしています。これらの文字列は関数によって継続的に生成されますgen_x
。
この関数はgen_x
時々(条件が満たされた場合にのみ)新しい文字列を出力します。私は現在、gen_x
無限ループでifステートメント(関数)を実装しています。この機能をrofiにパイプしたいです。 rofiで項目が選択されると、rofiは選択した項目を出力し、gen_x
rofiは終了する必要があります。
毎回新しい要素を出力する無限ループを使用すると(図を参照gen_b
)、スクリプトは上記のように正確に実行されます。ただし、関数でifステートメントを実装し、条件がtrueの場合にのみ新しい要素を印刷すると、プログラムは終了しません。これがrofiのためかどうかはわかりませんgen_x
。
コードを単純化する
gen_a(){ while true; do if [[ "$v" == "" ]]; then echo "Test"; v=1; fi; sleep 1; done }
gen_b(){ while true; do echo "Test"; sleep 1; done }
gen_a | rofi -dmenu # -> this outputs Test and does not end
gen_b | rofi -dmenu # -> this outputs Test and ends properly
whileループで条件を使用してプログラムを正しく終了させる方法はありますか?
答え1
rofi
いいえ非同期モードに切り替えるデフォルトでは、25行の入力を読み取る前です。これは次のように変更できます。
-async-pre-read [number]
非同期モードに切り替える前に複数のブロック項目を読み込む
オプション。
だから:
cmd | rofi -async-pre-read 1 -dmenu
1行を読むとすぐにメニューが表示されるようにしますcmd
。
項目を選択するとrofi
印刷され終了します。 cmd
その後、通常どおりstdout(今は壊れたパイプ)に書き込むとSIGPIPEによって終了します。
すぐに殺すための一般的な方法は次のとおりです。
sh -c 'echo "$$"; exec cmd' | {
IFS= read -r pid
rofi -async-pre-read 1 -dmenu
kill -s PIPE "$pid"
}