为什么赋值为零的这个变量的值是两个

Fle*_*phy 3 linux shell shell-script

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

当我运行这个脚本...

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

我得到输出...

0  
0  
Run Code Online (Sandbox Code Playgroud)

这是我所期望的。

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

#!/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
Run Code Online (Sandbox Code Playgroud)

我得到这个输出...

2  
2  
It IS a number  
2  
2  
enigma2 is running  
killall: enigma2: no process killed  
minisatip is already running 
Run Code Online (Sandbox Code Playgroud)

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

0  
0  
It IS a number  
enigma2 is not running  
minisatip is already running  
Run Code Online (Sandbox Code Playgroud)

为什么是这三行:

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

正确地将$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"
Run Code Online (Sandbox Code Playgroud)

在 /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
...
....
Run Code Online (Sandbox Code Playgroud)

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

在此处输入图片说明

我正在检查的进程是一个带有路径的二进制文件:/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 没有运行,结果应该为零。

谢谢!

柔性

小智 5

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

你只需要调试你的第二个脚本来找出为什么该命令产生不同的值,这样做(并且只是为了调试目的)替换

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

ENIGMA_PID=$(ps ax|grep enigma2|grep -v grep)
echo $ENIGMA_PID
echo "$ENIGMA_PID"
Run Code Online (Sandbox Code Playgroud)

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


ImH*_*ere 5

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

/bin/sh enigma2.sh
Run Code Online (Sandbox Code Playgroud)

您可以通过简单地将该脚本的第一行制作为以下内容来确认这一点:

#!/bin/sh 
ps ax|grep enigma2
exit 0
...
Run Code Online (Sandbox Code Playgroud)

您不需要擦除脚本,只需将上面显示的行放在脚本的开头,其余的都留在下面。

运行它得到:

$ enigma2.sh
 3109 pts/6    S+     0:00 /bin/sh enigma2.sh
 3111 pts/6    S+     0:00 grep enigma2
Run Code Online (Sandbox Code Playgroud)

有两个进程包含这个词enigma2

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

/bin/sh enigma2.sh
Run Code Online (Sandbox Code Playgroud)

并运行它:

$ 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
Run Code Online (Sandbox Code Playgroud)

当您使用$(…)一个额外的进程时出现。

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

那就是你得到的数字2

注意:请不要使用大写的变量名,它们是为环境变量保留的。
不要使用ENIGMA_PID

解决方案

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

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

     grep '[e]nigma2$'
    
    Run Code Online (Sandbox Code Playgroud)

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

enigma_pid=$(ps ax | grep -c '[e]nigma2$')
Run Code Online (Sandbox Code Playgroud)

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

编辑脚本:

#!/bin/sh 
ps ax|grep enigma2
exit 0
...
Run Code Online (Sandbox Code Playgroud)