等待进程结束或用户输入继续
Wait for process to end OR user input to continue
我有一个在后台运行命令的 bash 脚本。执行后,它会向用户显示:Press any key to continue
(由 read -n1 -r -p 'Press any key to continue' value
提供支持)
我想要在后台监视命令以查看它何时完成,如果是,我希望脚本继续执行。另一方面,这个过程可能仍在继续,我想让用户按下一个键来 kill
该过程,而不是等待它完成。
我想最简单的可视化方法是这样的:
用户可以等待计时器归零,它会自动关机,或者如果他们点击关机按钮,它会立即关机。
类似的内容可能适合您
#!/bin/bash
doStuff() {
local pidOfParent=""
for i in $(seq 10); do
echo "stuff ${i}" > /dev/null
sleep 1
done
kill $pidOfParent
}
doStuff $$ &
doStuffPid="$!"
read -n1 -rp 'Press any key to continue' && kill $doStuffPid
分解
doStuff
是我们的函数,它包含您想要在背景中呈现的内容 运行,即音乐。
$$
是 运行 脚本的 PID,我们将其传递给我们的函数以成为更具描述性的 pidOfParent
,我们在其中 kill
做完事情了。
函数调用后&
置于后台
$!
得到最后执行的命令的PID,这样我们就得到了刚刚启动的后台进程的PID。
你提供了 read -n1 -rp 'Press any key to continue'
所以我可以假设你已经知道那是做什么的,&& kill $doStuffPid
将在 read
退出时 kill
后台进程(这也适用于您使用 ^C
).
终止脚本
如果你想在用户按下某个键之前等待 pid,你可以按如下方式进行:
./long_command.sh &
waitpid=$!
echo "Hit any key to continue or wait until the command finishes"
while kill -0 ${waitpid} > /dev/null ; do
#if [[ ${#KEY} -gt 0 ]] ; then
if read -n 1 -t 1 KEY ; then
kill ${waitpid}
break
fi
done
只需将 long_command.sh
替换为您的命令即可。这里 $!
return 是最后启动的子进程的 pid,kill -0 ${waitpid}
检查进程是否仍然存在(它不会终止进程)。 ps -q ${waitpid}
也适用于 Linux,但不适用于 Mac - 谢谢@leetbacoon 提到这一点。 read -n 1 -t 1
表示 "read one character, but only wait up to 1 second"(您也可以在此处使用分数,例如 0.5)。 return 此命令的状态取决于它是否可以在指定时间内读取一个字符。
如果愿意使用嵌入式expect,可以这样写:
expect <(cat <<'EOD'
spawn sleep 10
send_user "Press any key to continue\n"
stty raw -echo
expect {
-i $user_spawn_id -re ".+" {}
-i $spawn_id eof {}
}
EOD
)
用您的流程替换 sleep 10
的地方。
我有一个在后台运行命令的 bash 脚本。执行后,它会向用户显示:Press any key to continue
(由 read -n1 -r -p 'Press any key to continue' value
提供支持)
我想要在后台监视命令以查看它何时完成,如果是,我希望脚本继续执行。另一方面,这个过程可能仍在继续,我想让用户按下一个键来 kill
该过程,而不是等待它完成。
我想最简单的可视化方法是这样的:
用户可以等待计时器归零,它会自动关机,或者如果他们点击关机按钮,它会立即关机。
类似的内容可能适合您
#!/bin/bash
doStuff() {
local pidOfParent=""
for i in $(seq 10); do
echo "stuff ${i}" > /dev/null
sleep 1
done
kill $pidOfParent
}
doStuff $$ &
doStuffPid="$!"
read -n1 -rp 'Press any key to continue' && kill $doStuffPid
分解
doStuff
是我们的函数,它包含您想要在背景中呈现的内容 运行,即音乐。
$$
是 运行 脚本的 PID,我们将其传递给我们的函数以成为更具描述性的 pidOfParent
,我们在其中 kill
做完事情了。
函数调用后&
置于后台
$!
得到最后执行的命令的PID,这样我们就得到了刚刚启动的后台进程的PID。
你提供了 read -n1 -rp 'Press any key to continue'
所以我可以假设你已经知道那是做什么的,&& kill $doStuffPid
将在 read
退出时 kill
后台进程(这也适用于您使用 ^C
).
如果你想在用户按下某个键之前等待 pid,你可以按如下方式进行:
./long_command.sh &
waitpid=$!
echo "Hit any key to continue or wait until the command finishes"
while kill -0 ${waitpid} > /dev/null ; do
#if [[ ${#KEY} -gt 0 ]] ; then
if read -n 1 -t 1 KEY ; then
kill ${waitpid}
break
fi
done
只需将 long_command.sh
替换为您的命令即可。这里 $!
return 是最后启动的子进程的 pid,kill -0 ${waitpid}
检查进程是否仍然存在(它不会终止进程)。 ps -q ${waitpid}
也适用于 Linux,但不适用于 Mac - 谢谢@leetbacoon 提到这一点。 read -n 1 -t 1
表示 "read one character, but only wait up to 1 second"(您也可以在此处使用分数,例如 0.5)。 return 此命令的状态取决于它是否可以在指定时间内读取一个字符。
如果愿意使用嵌入式expect,可以这样写:
expect <(cat <<'EOD'
spawn sleep 10
send_user "Press any key to continue\n"
stty raw -echo
expect {
-i $user_spawn_id -re ".+" {}
-i $spawn_id eof {}
}
EOD
)
用您的流程替换 sleep 10
的地方。