메뉴를 종료하지 않고 메뉴에서 종료 스크립트 호출

메뉴를 종료하지 않고 메뉴에서 종료 스크립트 호출

나는 여러 스크립트가 필요한 이 메뉴를 작성했습니다. 스크립트 중 하나는

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-terminal.lxterminal

쉘 스크립트:

#!/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

관련 정보