スイッチケースがシェルで動作しない

スイッチケースがシェルで動作しない

私はそれを使用してgdialogユーザー入力を受け取り、それをシェルのスイッチケースに供給する予定です。以下は私のコードです。

#!/bin/sh


which gdialog 2> /dev/null && DIALOG=gdialog || DIALOG=dialog

end () {
    # rm -f $FILE1 $FILE2 $ERROR
    echo "User pressed cancel!"
exit
}

while true
do
    choice=$($DIALOG --title "Messenger" --menu "Command" 8 35 8 \
    "Date" "Get today's date" \
    "Time" "Get today's time")|| end

    # echo $choice

    case "$choice" in
            "Date")

            MSG="Date is requested"
            echo $MSG
            $DIALOG --yesno "$MSG" 7 20 || end          
     ;;
            "Time")
            MSG="Time is requested!"
            $DIALOG --yesno "$MSG" 7 20 || end          
     ;;
    esac
done

問題は、スイッチケースが実行され、制御フローが最初のケースまたは2番目のケースに達しましたが、MSG変数宣言の後の行は実行されないことです。はい/いいえを使用してユーザーに続行するかどうかを尋ねますgdialog。私がここで何を間違っているのか?

答え1

コマンド置換は、コマンドの標準出力に置き換えられます。ダイアログボックスはstdoutを使用してUIを表示しますが、gdialog afaikはこれをまったく使用しません。どちらもstderrを使用して結果を返します。

スクリプトが期待どおりに動作するようにする1つの方法は、コマンドの置き換えでstdoutをstderrに置き換えることです。

choice=$($DIALOG --title "Messenger" --menu "Command" 8 35 8 \
"Date" "Get today's date" \
"Time" "Get today's time" 3>&2 2>&1 1>&3)|| end

答え2

dialogリダイレクトを使用していくつかの回避策を実行するか、オプションを使用しない限り、結果を標準エラーに記録します--stdout。これは、すべてのCursアプリケーションと同様に、デフォルトで結果を標準出力に記録し、標準エラーに報告するためです。 withはgdialog表示内容を別のウィンドウに記録するので気付かないでしょう。

gdialog私が書く理由はまさにこれです。何もない標準出力に送信され、$choice空です。スクリプトは Case 文を実行しますが、どの Case とも一致しません。通常、Caseステートメントにはデフォルト値が必要です。たとえば、次のようになります。*)メッセージを残すためにそこ何が起こったのか見てください。

問題のある部分ではありませんが、どのようにこの問題の解決が期待されるようです。gdialogスクリプト呼び出しである可能性があるスクリプト参照zenityオリジナルgdialogはいずっと前に消えた)。どちらも--stdoutオプションではありませんが、これは両方の計画より高速です(参照2000年以降の変更ログエントリ)。ファイル記述子を標準出力とエラーに置き換えることで、シェルでこの問題を解決できます。これは、Carey Evans(tn5250開発者)のアドバイスに従って、2000年後半からダイアログボックスのサンプルスクリプトにも登場しました。

    使用せずにダイアログボックスの出力をキャプチャできます。
    tn5250の "xt5250"スクリプトで行ったように、一時ファイルはまったくありません。

        3>&1を実行
        XT5250_HOST="`$DIALOG --backtitle "xt5250" --title "ホストに接続" \
          --inputbox "接続するホストの名前またはIPアドレスを入力してください:" \
          7 60 2>&1 1>&3 ``
        ret=$?
        実行3>&-

    たぶん、代わりにこのようなものを使用することを検討するかもしれません。
    一時ファイル。追加のfdトリックは実行するのが少し難しくなります。
    それでもぜひお読みください。

    >(単なる例ですが、セキュリティを維持するにはどれくらいの努力が必要ですか?)

    人々はそれを切り取り、貼り付けます。

同意します。スクリプトを停止して説明するのが役立ちます。ここでbashドキュメントが役に立ちます。ファイル記述子の移動。このスクリプト

(sh myscript.sh 3>&2 2>&1 1>&3) 2>/dev/null

(a)ファイル記述子1を移動する(標準出力)〜3、2(標準エラー)から1へ、次に3(オリジナル)へ標準出力)~2.

したがって、同じ一連の変更をファイル記述子に貼り付けてスクリプトを改善できます。

3>&2 2>&1 1>&3

次に割り当てられた場合choice

choice=$($DIALOG --title "Messenger" --menu "Command" 8 35 8 \
"Date" "Get today's date" \
"Time" "Get today's time" 3>&2 2>&1 1>&3 )|| end

追加資料:

関連情報