1

这是我的shell脚本:

#!/bin/bash
PIDS=$(ps -e | grep $1 |grep -v grep| awk '{print $1}')
kill -s SIGINT $PIDS
echo "Done sendings signal"

我将进程的名称作为命令行参数传递。
echo 命令没有被执行,尽管目标进程实际上正在接收 SIGINT 信号并退出。

有什么建议么?

更新:
我将代码更改为:

#!/bin/bash
PIDS=$(ps -e |grep $1 | grep -v grep | awk '{print $1}'|grep -v $$)
echo $PIDS
kill -s SIGINT $PIDS
echo "Done sendings signal"
echo "The current process is $$"

现在我注意到一件奇怪的事情:
脚本正在运行,但没有达到预期。在脚本外部的命令行中执行以下命令
ps -e|grep process-name|grep -v grep|awk '{print $1}'|grep -v $$
会给出进程名称的 pid,但是当我在 shell 脚本中执行相同的命令时,将其分配给变量 PIDS,然后回显 PIDS,然后除了进程的 pid 之外,它还会显示一个 pid-姓名。因此,当 kill 命令执行时,它会给出一个错误,即第二个 pid 的进程不存在。它确实与终端中的剩余句子相呼应。有什么线索吗?

4

3 回答 3

1

实际上只有几种可能性。假设你只是从命令行运行它,你应该看到消息......当然,除非你正在做的事情将你的 shell 进程的 PID 放在 PIDS 中,在这种情况下,kill 会杀死 (sub ) shell 在你点击回声之前运行你的命令。

建议:在调用 kill 之前 echo $PIDS 看看有什么。事实上,我很想注释掉 kill 并尝试该命令,看看会发生什么。

#!/bin/bash
PIDS=$(ps -e | grep $1 |grep -v grep| awk '{print $1}')
echo $PIDS
# kill -s SIGINT $PIDS
echo "Done sendings signal"

当然,您可以随时运行脚本bash -x来查看所有内容。

于 2012-07-07T14:40:37.000 回答
0

您的脚本有效。我可以看到未执行回显的唯一原因是 $1 的某些值和脚本文件名结合在一起,因此您的脚本 PID 也被收集,从而使脚本自杀。

PIDS 行产生一个运行 ps、grep 和另一个 grep 的进程——所以你不会在 PIDS 中找到运行 grep 的进程,但是父进程本身呢?

尝试:

#!/bin/bash
PIDS=$(ps -e | grep $1 |grep -v grep | awk '{print $1}' | grep -v "^$$\$" )
kill -s SIGINT $PIDS
echo "Done sendings signal"

或使用合适的安全 greps 一个接一个地运行管道。

编辑:很明显,“$1”的选择太多了。所以我会像这样重写脚本:

#!/bin/bash
# Gather the output of "ps -e". This will also gather the PIDs of this
# process and of ps process and its subshell.
PSS=$( ps -e )
# Extract PIDs, excluding this one PID and excluding a process called "ps".
# Don't need to expunge 'grep' since no grep was running when getting PSS.
PIDS=$( echo "$PSS" | grep -v "\<ps\>" | grep "$1" | awk '{print $1}' | grep -v "^$$\$" )
if [ -n "$PIDS" ]; then
    kill -s SIGINT $PIDS
else
    echo "No process found matching $1"
fi
echo "Done sending signal."
于 2012-07-07T14:41:07.800 回答
0

ps -e等同于ps -A并选择所有进程(参见http://linux.die.net/man/1/ps),即ps -e显示“有关其他用户进程的信息,包括那些没有控制终端的进程”(Mac OS X 的 man page ps)。这意味着您还将杀死$$您的 shell 进程的 PID ( ),正如 Charlie Martin 已经指出的那样,因为您还将 grep 如下ps -e所示的命令输出行:

67988 ttys000 0:00.00 /bin/bash ./killpids sleep

只需将 的输出记录ps -e到文件中即可查看您的脚本是否自杀:

./killpids sleep 2>err.log

#!/bin/bash
# cat killpids

echo $$

for n in {1..10}; do
   sleep 5000 &
done

sleep 1

unset PIDS
PIDS="$(ps -e | tee /dev/stderr | grep "$1" | grep -v grep | awk '{print $1}')"
#PIDS="$(ps -www -U $USER -o pid,uid,comm | tee /dev/stderr | grep "$1" | grep -v grep | awk '{print $1}')"

wc -l <<<"$PIDS"

#kill -s SIGINT $PIDS
echo kill -s TERM $PIDS
kill -s TERM $PIDS

echo "Done sendings signal"
于 2013-03-12T11:46:12.860 回答