我在这里编写了一个相当简单的脚本,用于显示使用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)
答案 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
注意:强>
urxvt
更改为xterm
,iTerm
或计算机中可用的任何其他终端emmulator。所以,也许这就是你需要的(未经测试):
#!/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"