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
将被检测为误报,也如评论所建议的那样。
从您编辑中可以清楚地看出,第二个脚本被称为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)