【问题标题】:Bash script not exiting once a process is running一旦进程运行,Bash脚本不会退出
【发布时间】:2020-03-11 05:02:34
【问题描述】:

我应该如何修改我的 bash 脚本逻辑,以便在我的本地 Ubuntu 18.04 上运行名为 custom_app 的进程时退出 while 循环并退出脚本本身?我尝试在 if 语句中使用 break 和 exit,但没有成功。

一旦自定义应用程序从...第一次尝试运行,然后我退出应用程序,run_custom_app.sh 会在后台徘徊并继续重试第二次、第三次、第四次、第五次。此时它应该什么都不做,因为应用程序已经成功运行并且用户有意退出。

下面是 run_custom_app.sh 用于运行我的自定义应用程序,该应用程序由网站按钮单击触发。

脚本逻辑

  1. 检查 custom_app 进程是否已经在运行。如果是这样,请不要运行 while 代码块中的命令。没做什么。退出 run_custom_app.sh。
  2. 当 custom_app 进程未运行时,最多重试 5 次。

  3. 一旦 custom_app 进程运行,停止 while 循环并退出 run_custom_app.sh。

  4. 如果尝试了 5 次运行重试,但 custom_app 进程仍未运行,则向用户显示一条消息。
#!/bin/sh

RETRYCOUNT=0
PROCESS_RUNNING=`ps cax | grep custom_app`

# Try to connect until process is running. Retry up to 5 times. Wait 10 secs between each retry.

while [ ! "$PROCESS_RUNNING" ] && [ "$RETRYCOUNT" -le 5 ]; do
  RETRYCOUNT="`expr $RETRYCOUNT + 1`"

  commands

  sleep 10

  PROCESS_RUNNING=`ps cax | grep custom_app`

  if [ "$PROCESS_RUNNING" ]; then
    break
  fi
done


# Display an error message if not connected after 5 connection attempts
if [ ! "$PROCESS_RUNNING" ]; then
  echo "Failed to connect, please try again in about 2 minutes"   # I need to modify this later so it opens a Terminal window displaying the echo statement, not yet sure how.
fi

【问题讨论】:

  • 我假设commands 表示运行您的进程的命令?您是否在进程启动后将其置于后台?
  • @StephenNewell 两者都是。

标签: bash


【解决方案1】:

我已经在VirtualBox 上测试了此代码,以替代您的custom_app,上一篇文章使用until 循环和pgrep 而不是ps。正如DavidC.Rankin 所建议的,pidof 更正确,但如果你想使用ps,那么我建议使用ps -C custom_app -o pid=

#!/bin/sh

retrycount=0

until my_app_pid=$(ps -C VirtualBox -o pid=); do  ##: save the output of ps in a variable so we can check/test it for later.
  echo commands  ##: Just echoed the command here not sure which commands you are using/running.
  if [ "$retrycount" -eq 4 ]; then ##: We started at 0 so the fifth count is 4
    break  ##: exit the loop 
  fi
  sleep 10
  retrycount=$((retrycount+1))  ##: increment by one using shell syntax without expr
done

if [ -n "$my_app_pid" ]; then  ##: if $my_app_pid is not empty
  echo "app is running"
else
  echo "Failed to connect, please try again in about 2 minutes"  >&2 ##: print the message to stderr 
  exit 1 ##: exit with a failure which is not 0
fi
  • my_app_pid=$(ps -C VirtualBox -o pid=) 变量赋值有一个有用的退出状态,因此我们可以使用它。

  • 基本上,until 循环与 while 循环正好相反。

【讨论】:

  • 为什么不if pidof VirtualBox; then echo "running" else echo "not"; fi?如果您愿意,可以将其与 until 一起使用。
  • @DavidC.Rankin,谢谢你的精彩评论,当然它也可以替代,但我会把这个答案留给其他人。也许你先生。
  • 你有的没问题,pidof 更直接一点。