解决方案

解决方案

我正在尝试创建一个脚本,当名为“enigma2”的进程不存在时,该脚本会用零填充变量。

当我运行这个脚本时...

#!/bin/sh
ENIGMA_PID=$(ps ax|grep enigma2|grep -v grep|wc -l | awk '{print $1}')
echo $ENIGMA_PID
echo "$ENIGMA_PID"

我得到输出...

0  
0  

这正是我所期望的。

但是当我运行这个脚本时:

#!/bin/sh

# Check if the no_enigma file exists
if [ -f /home/root/no_enigma ]; then
    # If enigma2 is running then kill it
    ENIGMA_PID=$(ps ax|grep enigma2|grep -v grep|wc -l | awk '{print $1}')
    echo $ENIGMA_PID
    echo "$ENIGMA_PID"

    re='^[0-9]+([.][0-9]+)?$'
    if ! [[ $ENIGMA_PID =~ $re ]] ; then
       echo "error: Not a number" >&2; exit 1
    else
        echo "It IS a number"
    fi

        if [ "$ENIGMA_PID" -gt 0 ]; then
            echo $ENIGMA_PID
            echo "$ENIGMA_PID"
            echo "enigma2 is running"
            killall enigma2
        else
            echo "enigma2 is not running"       
        fi
    # Check if minisatip is running already, if not then start it
    MINI_PID=$(ps ax|grep minisatip|grep -v grep|wc -l | awk '{print $1}')
        if [ "$MINI_PID" -gt 0 ]; then
            echo "minisatip is already running"
        else
            echo "minisatip is not running"
            echo "starting minisatip"
            /usr/bin/minisatip --satip-xml http://127.0.0.1:8554 -R /usr/share/minisatip/html       
        fi
else
    # The no_enigma file does not exist
    # Check if minisatip is running, if yes then kill it
    MINI_PID=$(ps ax|grep minisatip|grep -v grep|wc -l | awk '{print $1}')
        if [ "$MINI_PID" -gt 0 ]; then
            echo "minisatip is running, killing it now"
            killall minisatip
        else
            echo "minisatip is not running"
        fi  
    # Check if enigma2 is running already, if not then start it
    ENIGMA_PID=$(ps ax|grep enigma2|grep -v grep|wc -l | awk '{print $1}')
        if [ "$ENIGMA_PID" -gt 0 ]; then
            echo "enigma2 is already running"
        else
            echo "enigma2 is not running"
            echo "starting enigma2"
            /home/root/run_enigma.sh            
        fi
fi

我得到这个输出...

2  
2  
It IS a number  
2  
2  
enigma2 is running  
killall: enigma2: no process killed  
minisatip is already running 

如果我#!/bin/sh从第二个脚本的顶部删除,我会得到预期的输出。

0  
0  
It IS a number  
enigma2 is not running  
minisatip is already running  

为什么要执行这三行:

#!/bin/sh
ENIGMA_PID=$(ps ax|grep enigma2|grep -v grep|wc -l | awk '{print $1}')
echo $ENIGMA_PID
echo "$ENIGMA_PID"

正确地将$ENIGMA_PID变量报告为值为 0
但在第二个脚本中,同样的三行将变量报告$ENIGMA_PID为值为 2?

更新

这是下面评论中问题的答案。

此屏幕截图显示我正在运行这两个脚本。每次 minisatip 进程运行而 enigma2 进程未运行时。

在此输入图像描述

第一个脚本(只有 3 或 4 行)的路径是 /home/root/test.sh 我可以从任何地方运行它,看起来就像这样# test.sh
第二个脚本的路径是 /usr/bin /enigma2.sh 正如你所看到的,我运行它就像enigma2.sh

按照建议,我更新了两个脚本以从管道命令中删除 wc 和 awk,其输出旨在为变量赋值:ENIGMA_PID

我将 /home/root/test.sh 更改为:

#!/bin/sh
ENIGMA_PID=$(ps ax|grep enigma2|grep -v grep)
echo $ENIGMA_PID
echo "$ENIGMA_PID"

在 /usr/bin/enigma2.sh 中,我将这些行添加到脚本的顶部......

#!/bin/sh
ENIGMA_PID=$(ps ax|grep enigma2|grep -v grep)
echo $ENIGMA_PID
echo "$ENIGMA_PID"

# Check if the no_enigma file exists
...
....

现在我运行脚本,这个屏幕截图显示了输出。

在此输入图像描述

我正在检查的进程是一个二进制文件,路径为:/usr/bin/enigma2。该二进制文件未运行。然而,当 enigma2.sh 脚本运行时,有两个进程 ID。这是因为脚本本身被称为 enigma2 吗?那么为什么他们的两个进程 id 被称为 enigma2 而不是一个呢?

问题
我需要在此命令中更改什么
ENIGMA_PID=$(ps ax|grep enigma2|grep -v grep|wc -l | awk '{print $1}')

...当它位于名为 /usr/bin/enigma2.sh 的脚本中时
...所以它不计算脚本,它是作为正在运行的进程的一部分?
...如果二进制文件 /usr/bin/enigma2 未运行,结果应为零。

谢谢你!

柔性

答案1

从您的编辑中可以清楚地看出,第二个脚本被称为enigma2.sh,并且您通过enigma2.sh在命令行上编写来调用它。该脚本位于您的路径中的某个位置(您声明它位于 at /usr/bin/enigma2.sh,我假设它/usr/bin位于您的 PATH 变量中)。结合 shell 可以找到的脚本(在 PATH 中)以及脚本的第一行是#!/bin/sh,内核将启动一个新进程,其命令行为:

/bin/sh enigma2.sh

您可以通过简单地将该脚本的第一行设置为如下来确认这一点:

#!/bin/sh 
ps ax|grep enigma2
exit 0
...

您不需要删除脚本,只需将上面显示的行放在脚本的开头,并将其余所有内容保留在下面。

运行即可得到:

$ enigma2.sh
 3109 pts/6    S+     0:00 /bin/sh enigma2.sh
 3111 pts/6    S+     0:00 grep enigma2

有两个过程包含单词enigma2

这解释了部分问题。现在,如果您将脚本更改为:

#!/bin/sh 
enigma_pid=$(ps ax|grep enigma2)
echo "$enigma_pid"
exit 0
...                     # leave the old script below (no need to erase it).

并运行它:

$ enigma2.sh
 3509 pts/6    S+     0:00 /bin/sh ./enigma2.sh
 3510 pts/6    S+     0:00 /bin/sh ./enigma2.sh
 3512 pts/6    S+     0:00 grep enigma2

当您使用时$(…)会出现一个附加进程。

删除 grep 进程并grep -v grep留下 2 个进程。

这就是您得到的数字2

笔记:请不要使用大写变量名称,这些名称是为环境变量保留的。
不要使用ENIGMA_PID

解决方案

  • 第一:如果您要通过名称来识别进程,请不要在其他程序或脚本中使用完全相同的名称。您可以调用该脚本enigma33.sh

  • 其次:在这种情况下,您可以限制 grep 匹配以 结尾的名称2。脚本以 结尾.sh且不会被计算在内。使用

     grep '[e]nigma2$'
    

并且,由于您需要的只是匹配行的计数,因此请使用 ( -c):

enigma_pid=$(ps ax | grep -c '[e]nigma2$')

是的,不需要,grep -v grep因为正则表达式[e]nigma2$不能等于(作为字符串)enigma2

编辑后的脚本:

#!/bin/sh


# Detect If enigma2 is running.
enigma_pid=$(ps ax|grep -c '[e]nigma2$')
echo "$enigma_pid"    

# Deetct if minisatip is running.
mini_pid=$(ps ax|grep -c '[m]inisatip$' )


# Check if the no_enigma file exists
if [ -f /home/root/no_enigma ]; then
    if [ -z "${enigma_pid##*[!0-9]*}" ] ; then
       echo "error: Not a number" >&2; exit 1
    else
        echo "It IS a number"
    fi
    
    if [ "$enigma_pid" -gt 0 ]; then
        echo "$enigma_pid"
        echo "enigma2 is running"
        killall -r '[e]nigma2$'           # make killing more restrictive
    else
        echo "enigma2 is not running"
    fi
    # Check if minisatip is running already, if not then start it
    if [ "$mini_pid" -gt 0 ]; then
        echo "minisatip is already running"
    else
        echo "minisatip is not running"
        echo "starting minisatip"
        /usr/bin/minisatip --satip-xml http://127.0.0.1:8554 -R /usr/share/minisatip/html       
    fi
else    
    # The no_enigma file does not exist
    # Check if minisatip is running, if yes then kill it
    if [ "$mini_pid" -gt 0 ]; then
        echo "minisatip is running, killing it now"
        killall minisatip
    else
        echo "minisatip is not running"
    fi  
    # Check if enigma2 is running already, if not then start it
    if [ "$enigma_pid" -gt 0 ]; then
        echo "enigma2 is already running"
    else
        echo "enigma2 is not running"
        echo "starting enigma2"
        /home/root/run_enigma.sh            
    fi
fi

答案2

正如所解释的,ps ax从第二个脚本运行时,命令确实会产生不同的结果。

您只需要调试第二个脚本即可找出该命令产生不同值的原因,这样做(仅用于调试目的)替换

ENIGMA_PID=$(ps ax|grep enigma2|grep -v grep|wc -l | awk '{print $1}')
echo $ENIGMA_PID
echo "$ENIGMA_PID"

ENIGMA_PID=$(ps ax|grep enigma2|grep -v grep)
echo $ENIGMA_PID
echo "$ENIGMA_PID"

并检查输出的真正不同之处以及导致问题的原因......然后相应地调整您的脚本。如果您的脚本也如评论所建议姓名包含enigma2将被检测为误报。

相关内容