linux 怎么做:1.子终端内并行运行的进程,子终端关闭后继续运行2.父脚本等待进程结束

ukqbszuj  于 2023-03-17  发布在  Linux
关注(0)|答案(1)|浏览(133)

我想创建一个bash脚本,并满足以下要求:
要求:
脚本:

  • 并行启动多个进程的执行
  • 在继续其自身的执行之前等待进程完成执行。

每个过程:

  • 需要相对较长的时间才能完成执行
  • 应该将其日志输出到子gnome终端窗口和日志文件,该文件应该与其他进程的终端窗口和日志文件以及父脚本使用的终端窗口不同。
  • 即使用户关闭了相应的子gnome终端窗口也不会结束。这意味着即使用户关闭了子gnome终端窗口或在子gnome终端窗口上按了ctrl+c,它也会继续运行并将日志输出到相应的日志文件中。

我的尝试:
我尝试用下面的代码来实现这一点:

nohup gnome-terminal --wait -- bash -c "cd /home;find . -name "foo*" | tee /home/$USER/log-home.txt" &
nohup gnome-terminal --wait -- bash -c "cd /home/$USER; find . -name "foo*" | tee /home/$USER/log-$USER.txt" &
wait;
echo "Finished";

代码abgove不符合预期要求,但:

  • 如果我关闭了一个子窗口,在它里面运行的进程停止输出日志到相应的日志文件,我猜这个进程刚刚结束运行。
  • 如果我关闭从父脚本启动的所有子gnome终端窗口,父脚本将继续运行wait命令之后的脚本行。
db2dz4w8

db2dz4w81#

这是一个尝试去完成你所确定的东西的尝试。逻辑流应该是所需要的,但是当执行时,它表现得“不稳定”,这意味着窗口正在“死亡”,但是仅仅是在最初的持久化之后。我看不出是什么杀死了预期无限期运行的进程。也许更专业的人可以发现我遗漏了什么。

所以,这是脚本

#!/bin/bash

logdir="$(pwd)"

seconds=6
others=$((seconds+=1))
matchCommand="sleep ${seconds}"

terminal="gnome-terminal"
terminal="mate-terminal"

jobOne="${logdir}/job1.sh"
cat >"${jobOne}" <<EnDoFiNpUt
while true
do
    date
    ${matchCommand}
done > ${logdir}/Output.txt
EnDoFiNpUt
chmod 750 "${jobOne}"

jobTwo="${logdir}/job2.sh"
cat >"${jobTwo}" <<EnDoFiNpUt
while true
do
    date
    ${matchCommand}
done > ${logdir}/WORKS.txt
EnDoFiNpUt
chmod 750 "${jobTwo}"

actionOne="${logdir}/action1.sh"
cat >"${actionOne}" <<EnDoFiNpUt
echo 'waiting ${others} sec to execute ...'
sleep ${others}
cd ${logdir}/Output
nohup ${jobOne} &
RC_loop=\$?
echo "Process ID for loop = \${RC_loop} ..."
sleep ${others} ; tail -f ${logdir}/Output.txt | awk -v cmd=\`basename \$0 \` '{ printf("%s| %s\n", cmd, \$0 ) ; }' &
RC_tail=\$?
echo "Process ID for tail = \${RC_tail} ..."
while true
do
    sleep ${others}
    testor=\`ps -e | awk -v procID=\"\${RC_loop}\" '{ if( \$1 == procID ){ print \$0 } ; }' \`
    if [ -z "\${testor}" ]
    then
        kill -9 \${RC_tail}
        break
    fi
    echo -e "\t Process \${RC_loop} is still running ..."
done
echo -e "\n Hit return to close window ..." ; read k
EnDoFiNpUt
chmod 750 "${actionOne}"

actionTwo="${logdir}/action2.sh"
cat >"${actionTwo}" <<EnDoFiNpUt
echo 'waiting ${others} sec to execute ...'
sleep ${others}
cd ${logdir}/WORKS
nohup ${jobTwo} &
RC_loop=\$?
echo "Process ID for loop = \${RC_loop} ..."
sleep ${others} ; tail -f ${logdir}/WORKS.txt | awk -v cmd=\`basename \$0 \` '{ printf("%s| %s\n", cmd, \$0 ) ; }' &
RC_tail=\$?
echo "Process ID for tail = \${RC_tail} ..."
while true
do
    sleep ${others}
    testor=\`ps -e | awk -v procID=\"\${RC_loop}\" '{ if( \$1 == procID ){ print \$0 } ; }' \`
    if [ -z "\${testor}" ]
    then
        kill -9 \${RC_tail}
        break
    fi
    echo -e "\t Process \${RC_loop} is still running ..."
done
echo -e "\n Hit return to close window ..." ; read k
EnDoFiNpUt
chmod 750 "${actionTwo}"

shell_command="bash"

${terminal} --execute ${shell_command} -c "${actionOne}" &
${terminal} --execute ${shell_command} -c "${actionTwo}" &

PIDs=""

for PID in `ps -ef |
    grep "${matchCommand}" |
    grep -v grep |
    awk -v com="${shell_command}" '{ if( $8 == com ){ print $3 } ; }' `
do
    PIDs="${PIDs} ${PID}"
done

sleep 4
if [ -n "${PIDs}" ] ; then  ps -ef ${PIDs} ; fi
ls -ld ${logdir}/Output.txt
ls -ld ${logdir}/WORKS.txt

if [ -n "${PIDs}" ] ; then  wait ${PIDs} ; fi
echo "Finished";

相关问题