Zenity Progressダイアログのキャンセルボタンはどのように機能しますか?

Zenity Progressダイアログのキャンセルボタンはどのように機能しますか?

Cancel私はZenityウィンドウの--progressボタンが私のスクリプトで動作するようにしようとしましたが、CancelZenityのマニュアルページに表示されている例では、ボタンがどのように機能するかを理解していないことに気づきました。https://help.gnome.org/users/zenity/stable/progress.html.en

#!/bin/sh
(
echo "10" ; sleep 1
echo "# Updating mail logs" ; sleep 1
echo "20" ; sleep 1
echo "# Resetting cron jobs" ; sleep 1
echo "50" ; sleep 1
echo "This line will just be ignored" ; sleep 1
echo "75" ; sleep 1
echo "# Rebooting system" ; sleep 1
echo "100" ; sleep 1
) |
zenity --progress \
  --title="Update System Logs" \
  --text="Scanning mail logs..." \
  --percentage=0

if [ "$?" = -1 ] ; then
        zenity --error \
          --text="Update canceled."
fi

Cancelこのスクリプトが実行されているときにボタンを押すか、他のコマンドが表示されないとプロセスが停止するのはなぜexitですかbreak

私はZenityがグラフィカルインタフェースを表示し、必要な実際のコマンド(キャンセルなど)を開始するために使用できる終了コードを返すプログラムだけだと思いましたが、exitZenityはより複雑な作業を実行する必要があるようです。例のコマンドは、ボタンを押したときに実際に停止する理由があるようです。

Zenityがもっと複​​雑な作業をしているのでしょうか、それとも私が間違って何かを理解したのでしょうか?私はbash / shスクリプトに最初に遭遇したので誤解しているようです。これが単にZenity独自のコンプリケーションであれば、それがどのように機能するかについての完全な技術的な説明は必要ありません。私が望むのは、それが安定して使用できるように十分な説明です。ありがとうございます。

(また、この例がなぜ公式マニュアルから出てきたのか尋ねたいと思います。実際には動作しません[Ubuntu 14.04] --errorZenityウィンドウがまったく表示されないため、StackExchangeは連合の質問が好きではないと仮定しているため、誤解を招く可能性があるものと関係がない限り問題ありません。 )

関連投稿: zenityプログレスバーを使用してスクリプトを終了する(最も高い回答に使用するように指示されているため、私の質問には答えません。--auto-killこの例では使用せず、プロセスはキャンセルされます。--auto-kill

ベストアンサー1

()スクリプトの構文を使用すると、sh次を開始できます。サブシェル。サブシェルを次の2行と考えることができます。

(echo foo)
sh -c "echo foo"

つまり、シェルスクリプトを処理する2番目のプロセスがあります。そのサブシェルの標準出力は、()パイプ記号( "")を介してzenityの標準入力に接続されています。|

zenityウィンドウでキャンセルボタンをクリックすると、zenityはすぐに終了します。この時点で、サブシェルの標準出力は無効になります。これはサブシェルをすぐに終了しません。ただし、echoサブシェルの次のコマンドがstdoutに書き込もうとすると、書き込もうとしているSIGPIPEパイプのリーダーがないことを知らせます。プロセスの標準動作はSIGPIPE終了です。

端末でスクリプトを実行して「キャンセル」ボタンをクリックすると、後ろに更新がzenityに送信され、sleepコマンドが実行され続け、sleepが出力を生成しないため、シェルプロンプトはすぐに返されません。出力が生成され放出されるまでに時間がかかりますSIGPIPE

この動作を望まない場合は、SIGPIPEを受け取った後にシェルを終了しないように指示する必要があります。

#!/bin/sh
(
    trap -- '' PIPE
    echo "10"; sleep 1
    # ... etc, your normal script goes here
) |
zenity --progress ...

このバージョンはこれを無視しSIGPIPE、zenityが終了すると幸せになります。ただし、この場合、「キャンセル」ボタンを押すとユーザーが非常に混乱する可能性があるため、zenityは終了します。いいえジョブが中断されます。ただ進むのが良いかもしれませんね--no-cancel

おすすめ記事