关闭背景zenity对话框时使脚本终止

时间:2018-02-09 17:28:29

标签: bash zenity

我在这里编写了一个相当简单的脚本,用于显示使用zenity的文本信息对话框,并从远程TCP连接中连续读取数据并在对话框中显示。这有效...但是如果我关闭zenity对话框,我希望整个脚本终止。

有办法做到这一点吗?我不认为我可以检查while循环中的任何内容,因为在从远程TCP连接读取数据时脚本可能会停止。

#!/bin/bash

on_exit() {
        zenity --display=:0 --error --text="Script has exited." &
}

# Options
while getopts "a:p:t:" OPTION; do case "$OPTION" in
        a) address="$OPTARG";;
        p) port="$OPTARG";;
        t) title="$OPTARG";;
esac; done

exec &> >(zenity --display=:0 --text-info --title=$title || exit)
                               # doesn't make a difference?  ↑
                               # also tried &&
trap "on_exit" EXIT

while read data < /dev/tcp/$address/$port; do
        echo $data
        # ...
        # do some other stuff with the information
        # ...
done

注意:这将在IGEL Linux上运行。我没有选择安装其他软件包的选项。所以,理想情况下,我正在寻找的解决方案是Bash原生的。

更新

我只需要进行此修改即可继续使用exec。或@BachLien使用命名管道的答案也有效。

PID=$$
exec &> >(zenity --display=:0 --text-info --title=$title; kill $PID)

2 个答案:

答案 0 :(得分:1)

我没有安装zenity,所以我尝试使用此脚本来说明这个想法。

程序terminal+cat(emmulating zenity)由在后台运行的函数_dspMsg执行(子进程); cat持续显示来自文件($m)的消息,该文件是命名管道;当kill退出时,父进程为terminal+cat

同时,另一个cat进程将消息写入管道$m(使用TPC信息提要);当_dspMsg退出时,它会被杀死。

#!/bin/bash
                              # 1) named pipe
m=`mktemp -u /tmp/msg-XXXX=`  #    get a temporary filename (for named pipe)
mkfifo "$m"                   #    create that named pipe
trap "echo END; rm $m" EXIT   #    remove that file when exit
                              # 2) zenity
_dspMsg(){                    #    continuously display messages
  urxvt -e bash -c "cat <$m"  #    terminal+cat is used in place of zenity
  kill $1                     #    kill parent pid
}                             #    to be run in background
_dspMsg $$ &                  #    $$ = proccess id
                              # 3) TCP info feeds
cat >>"$m"                    #    feeding messages using cat
                              #    cat is used in placed of TCP data feed

注意:

  1. 命名管道用作父进程和子进程之间的通信方式。
  2. 要测试该脚本,您可能需要将urxvt更改为xtermiTerm或计算机中可用的任何其他终端emmulator。
  3. 所以,也许这就是你需要的(未经测试):

    #!/bin/bash
    
    while getopts "a:p:t:" OPTION; do case "$OPTION" in
      a) address="$OPTARG";;
      p) port="$OPTARG";;
      t) title="$OPTARG";;
    esac; done
    
    m=`mktemp -u /tmp/msg-XXXX=`
    mkfifo "$m"
    trap "zenity --display=:0 --error --text='Script has exited.' & rm $m" EXIT
    
    _dspMsg(){
      zenity --display=:0 --text-info --title="$title" <"$m"
      kill $1
    }
    
    _dspMsg $$ &
    
    while read data < /dev/tcp/$address/$port; do
      echo $data >>"$m"
    done
    

答案 1 :(得分:0)

您可以将while循环的所有输出都输入zenity,从而消除对exec &>的需求。

while read data < "/dev/tcp/$address/$port"; do
        echo "$data"
done | zenity --display=:0 --text-info --title="$title"