メニューを終了せずにメニューから終了スクリプトを呼び出す

メニューを終了せずにメニューから終了スクリプトを呼び出す

私はいくつかのスクリプトを必要とするこのメニューを書きました。スクリプトの1つは

dbus-monitor --system

したがって、dbusのリアルタイムトラフィックを表示します。

しかし、終了したいときは通常Ctrl+を使用しますCが、これも私のメニューを終了して私のメニューに戻りたいと思います。

シャットダウンが検出されたら、メニューを再起動するためにdbus-moniterの後ろに置くことができるコードはありますか?私のメニューは別の.shスクリプトです。

または…。

- - - - - - - - - 説明 - - - - - - - - -

私は「まだ」スクリプトに精通していません。これは dbus スクリプトを呼び出すメニューです。

select opt in "dbus Live Traffic" "option 2" "Main menu" "Quit"
    do
        case $opt in
            "dbus Live Traffic")
                curl -s -u lalala:hihihi ftp://ftp.somewhere.com/folder/dbuslivetraffic.sh | bash ;;   
            "option 2")
                do_something ;;   
            "Main menu")
                main_menu;;
            "Quit")
                quit_menu;;
        esac
        if [[ $opt != "Main menu" ]] || [[ $opt != "Quit" ]] ;
        then
            main_menu
        fi
    done

これは私のdbuslivetraffic.shの内容です。

dbus-monitor --system

現在はこの行だけですが、近いうちにこのスクリプトにさらにコードが追加されます。

TRAP@RoVoが提案したのと同じ機能をどこに置くべきかは本当にわかりません。

答え1

サブシェルでコマンドを実行し、実行中のサブシェルのtrapプロセスグループのみを終了できます。SIGINTkill 0

select opt in a b; do
    case $REPLY in
      1)
        (
          trap "kill -SIGINT 0" SIGINT
          sleep 10
        )
        ;;
      2)
        sleep 10
        ;;
    esac
done
  • (1)を選択すると、メニューを終了せずに Ctrl+を使用できます。c
  • (2)を選択してCtrl+を押してもcメニューが終了します.

答え2

グラフィックデスクトップ環境

別のターミナルウィンドウでこのコマンドを実行できます(グラフィックスデスクトップ環境がある場合)。

次のシェルスクリプトが使用され、xterm次のコマンドを使用してインストールできます

sudo apt update
sudo apt install xterm

しかし。gnome-terminallxterminal

シェルスクリプト:

#!/bin/bash

select opt in "dbus-monitor --system" htop exit; do
    case $REPLY in
      1)
        xterm -e dbus-monitor --system 2>/dev/null
        ;;
      2)
        htop
        ;;
      3)
        exit
        ;;
    esac
done

テキスト画面(この方法はグラフィックデスクトップでも機能します)

@RoVoの回答でトラップ方法を使用できます。

重要なのは、trapコマンドを実行することです今後ctrlコマンドを実行したら+で中断する必要がありますc

  • したがって、メニュースクリプト全体に表示されるようにするには、始めに入れます。

  • 必要な場合にのみ必要な場合は、trap@RoVoが提案したようにサブシェルを実行し、コマンドをサブシェルに入れるか、次を使用してください。

    bash -c 'trap "kill -SIGINT 0" SIGINT; dbus-monitor --system';;
    

シェルスクリプト:

#!/bin/bash

echo "Press the Enter key to print out the menu again"

trap "kill -SIGINT 0" SIGINT

select opt in "dbus-monitor --system" "option 2" "Quit"
do
    case $opt in
        "dbus-monitor --system")
            dbus-monitor --system;;   
        "option 2")
            echo "Hello World";;   
        "Quit")
            exit;;
    esac
done

コメント

コマンドラインが機能していないため、+を使用したときにシェルスクリプトが機能しているかどうかをテストするためにcurlローカルコマンドを呼び出しました。dbus-monitorctrlc

答え3

@pLumoに追加されました良い答え、次の関数を定義して、それぞれに必要なコード量を減らすことができますcase

run_in_subshell () {
    command="$@"
    (
        trap "kill -INT 0" INT
        $command
    )
}

それからcase

select opt in a b; do
    case $REPLY in
      1) run_in_subshell sleep 10 ;;
      2) sleep 10 ;;
    esac
done

関連情報