【问题标题】:Selectively switch bash script on and off from inside another bash script从另一个 bash 脚本中选择性地打开和关闭 bash 脚本
【发布时间】:2017-02-17 13:11:24
【问题描述】:

我有一个运行 bash 脚本(例如 ScriptA)的 Raspberry Pi,它调用在云服务器上运行的 Web 函数,该函数将一个值返回给调用脚本。云服务器包含一个系统,在该系统中,网站的访问者可以使用按钮获得一些选项,例如 Button1、Button2 和 Button3。访问者选择的选项由 Web 函数发送到 Pi 上的调用 bash 脚本,分别作为 Button1、Button 和 Button3 的 Request1、Request2 或 Request3。 ScriptA 不断递归调用 web 函数以检查请求值的任何变化。该函数返回给 Pi 的值随后用于在 Pi 上运行另一个脚本,例如,Request1 运行 Script1,Request2 运行 Script2,Request3 运行 Script3。现在,网页是动态的,访问者可以一个接一个地点击不同的选项,在树莓派上运行的脚本也需要相应地改变。


Button1 => Request1 |                              | Request1 => Script1
Button2 => Request2 | Cloud Server <=> Pi(ScriptA) | Request2 => Script2
Button3 => Request3 |                              | Request3 => Script3

我所做的是,我在 ScriptA 中使用了一个 switch case 在不同的脚本 1、2 和 3 之间切换。我想要的是,只要网站的访问者选择不同的选项并且 Pi接收到新请求,之前选择的选项的脚本停止执行,新请求的脚本开始执行。


#!/bin/bash
# call.sh

while:
do
    req=$(curl -d "param=$param" http://www.example.net/req.php)
    case $req in
        *req1*)
            sudo sh /home/pi/stopscript2.sh
            sudo sh /home/pi/stopscript3.sh
            sudo sh /home/pi/startscript1.sh
            ;;
        *req2*)
            sudo sh /home/pi/stopscript1.sh
            sudo sh /home/pi/stopscript3.sh
            sudo sh /home/pi/startscript2.sh
            ;;
        *req3*)
            sudo sh /home/pi/stopscript1.sh
            sudo sh /home/pi/stopscript2.sh
            sudo sh /home/pi/startscript3.sh
            ;;
        esac
done

但是,这段代码的问题在于,当 pi 第一次收到请求并开始执行传入请求的特定脚本时,此后不再调用 web 函数,脚本继续执行第一次请求,无论用户是否选择了新选项。

如何让它按需要工作?我希望我能很好地提出我的问题。

非常欢迎帮助。提前致谢。

【问题讨论】:

  • 所以,如果我理解正确的话,当你收到一个请求时,比如说*req1*,脚本会停止监听任何其他请求,直到stopscript2.shstopscript3.shstopscript1.sh 完成?如果是这种情况,您可以通过使用以下语法并行运行脚本轻松解决您的问题:stopscript2.sh &amp;
  • 有一个问题。 startscripts 1、2 和 3 包含无限 while 循环,当仅从命令行运行时,需要按 ctrl+c 才能停止执行。已编写停止脚本,以便它们终止相应的启动脚本。因此,当任何脚本开始执行时,程序流程会在该脚本内继续,并且不会返回调用 Web 函数的父脚本。
  • @DebopamParua: 是否有特殊需要使用 ctrl+c ?您能否查看我发布的解决方案,它应该可以实现您想要实现的目标,如果有些不合适,请让我们知道什么是不合适的。我们将尝试修改并再次查看。

标签: linux bash shell raspberry-pi3


【解决方案1】:

假设:

  1. 我们继续阅读新的输入,并执行新收集的 值,无论是“Request1”、“Reqest2”还是“Request3”并摆脱 旧的。
  2. 您不介意杀死而不是停止先前的进程。

除了您的方法之外,我还添加了以下内容:

  1. 日期、时间打印功能,清晰显示操作时间。验证功能后,可以稍后省略。

  2. 一个'getpid'函数,重新计算上一个运行脚本的pid并传递给kill函数

  3. 为了证明这一点,我将跟踪一个不断增长的文件 data.txt,因为 3 个背景回显命令不断将请求 1、2、3 放入其中。这将作为我们有点动态的随机输入。下面是一个示例。

示例:

%_STATION@gaurav * /root/ga/shell> tail -f data.txt
Request2
Request1
Request1
Request1
Request3
Request2
Request1

脚本输出:

  1. 带有 EMPTY 的行表示未找到 PID。 EMPTY
  2. 这表示从您的文件中读取了一个新请求:[17-02-17 20:38:17|[&gt;&gt;&gt;&gt;NEW&gt;&gt;&gt;REQUEST&gt;&gt; [Request3]&gt;&gt;&gt;&gt;]
  3. [gaurav 82577 1 0 20:38 pts/3 00:00:00 sleep 11]。这是旧的正在运行的进程,所以我现在将其杀死。
  4. 它的PID被捕获:[OLDPID----&gt;82577]
  5. 一旦被杀死,就会触发一个新的,它是“Request3”:[gaurav 82611 1 0 20:38 pts/3 00:00:00 sleep 13]
  6. 现在这种情况不断重复。请参阅下面的日志以获得更清晰的信息。

日志摘录:

17-02-17 20:38:16|EMPTY
17-02-17 20:38:16|[***NEWPROCESS***[82504]*****]
17-02-17 20:38:16|[>>>>NEW>>>REQUEST>> [Request1]>>>>]
17-02-17 20:38:16|gaurav    82504      1  0 20:38 pts/3    00:00:00 sleep 12
17-02-17 20:38:16|[OLDPID---->82504]
17-02-17 20:38:16|gaurav    82543      1  0 20:38 pts/3    00:00:00 sleep 11
17-02-17 20:38:16|[***NEWPROCESS***[82543]*****]
17-02-17 20:38:16|[>>>>NEW>>>REQUEST>> [Request1]>>>>]
17-02-17 20:38:16|gaurav    82543      1  0 20:38 pts/3    00:00:00 sleep 11
17-02-17 20:38:16|[OLDPID---->82543]
17-02-17 20:38:17|gaurav    82577      1  0 20:38 pts/3    00:00:00 sleep 11
17-02-17 20:38:17|[***NEWPROCESS***[82577]*****]
17-02-17 20:38:17|[>>>>NEW>>>REQUEST>> [Request3]>>>>]
17-02-17 20:38:17|gaurav    82577      1  0 20:38 pts/3    00:00:00 sleep 11
17-02-17 20:38:17|[OLDPID---->82577]
17-02-17 20:38:17|gaurav    82611      1  0 20:38 pts/3    00:00:00 sleep 13
17-02-17 20:38:17|[***NEWPROCESS***[82611]*****]
17-02-17 20:38:17|[>>>>NEW>>>REQUEST>> [Request2]>>>>]
17-02-17 20:38:17|gaurav    82611      1  0 20:38 pts/3    00:00:00 sleep 13
17-02-17 20:38:17|[OLDPID---->82611]
17-02-17 20:38:17|EMPTY
17-02-17 20:38:17|[***NEWPROCESS***[82664]*****]
17-02-17 20:38:17|[>>>>NEW>>>REQUEST>> [Request1]>>>>]
17-02-17 20:38:17|gaurav    82664      1  0 20:38 pts/3    00:00:00 sleep 12
17-02-17 20:38:17|[OLDPID---->82664]
17-02-17 20:38:17|gaurav    82699      1  0 20:38 pts/3    00:00:00 sleep 11
17-02-17 20:38:17|[***NEWPROCESS***[82699]*****]
17-02-17 20:38:17|[>>>>NEW>>>REQUEST>> [Request1]>>>>]
17-02-17 20:38:17|gaurav    82699      1  0 20:38 pts/3    00:00:00 sleep 11
17-02-17 20:38:17|[OLDPID---->82699]
17-02-17 20:38:18|gaurav    82733      1  0 20:38 pts/3    00:00:00 sleep 11
17-02-17 20:38:18|[***NEWPROCESS***[82733]*****]
17-02-17 20:38:18|[>>>>NEW>>>REQUEST>> [Request3]>>>>]
17-02-17 20:38:18|gaurav    82733      1  0 20:38 pts/3    00:00:00 sleep 11
17-02-17 20:38:18|[OLDPID---->82733]
17-02-17 20:38:18|gaurav    82767      1  0 20:38 pts/3    00:00:00 sleep 13
17-02-17 20:38:18|[***NEWPROCESS***[82767]*****]
17-02-17 20:38:18|[>>>>NEW>>>REQUEST>> [Request2]>>>>]
  1. 如以上日志所示,脚本现在能够根据传入的请求执行操作。在您的情况下,您可以将 tail -f data.txt | while read line 行部分替换为 while true; do,然后输入您的 curl 命令。

脚本:

%_STATION@gaurav * /root/ga/shell> cat request_action.sh
#!/bin/bash

# configure your scirpts. Here I used Sleeps.
s1='sleep 11' ; s2='sleep 12' ; s3='sleep 13'

# DateTime and print function.
prnt()
{
  str="$1"
  dt=$(date +"%d-%m-%y "%T)
  [[ -z "$str" ]] && str="EMPTY"
  echo "$dt|$str"
}
# Function to generate PID of previous running script.
getpid()
{
  pid=$(ps -ef|egrep "$s1|$s2|$s3"|grep -v grep|awk '{print $2}')
  echo "$pid"
}
# To kill the existing running script/s.
stopnstart()
{
   prnt "$(ps -ef|egrep "$s1|$s2|$s3"|grep -v grep)"
   prnt "[OLDPID---->$(getpid)]"
   $(kill -9 $(getpid) 1>/dev/null 2>&1)    # Kill the old PID.
   $($1  1>/dev/null 2>&1 &)    # Now run the fresh script.
   prnt "$(ps -ef|egrep "$s1|$s1|$s3"|grep -v grep)"
   prnt "[***NEWPROCESS***[$(getpid)]*****]"
}

# Main loop
tail -f data.txt | while read line
do
     prnt "[>>>>NEW>>>REQUEST>> [$line]>>>>]"
      case $line in

          Request1)
                stopnstart "$s1"
                ;;
          Request2)
                stopnstart "$s2"
                ;;
          Request3)
                stopnstart "$s3"
                ;;
      esac
done
%_STATION@gaurav * /root/ga/shell>

我希望我做对了。谢谢。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-26
    • 2016-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多