我该如何将Bash命令的输出存储到变量中?

8
我想写一个简单的脚本来杀死一个进程。我已经阅读了在bash和正则表达式中一行内查找和杀死进程,所以请不要让我去那里。
这是我的代码:
LINE=$(ps aux | grep '$1')
PROCESS=$LINE | awk '{print $2}'
echo $PROCESS
kill -9 $PROCESS

我希望能够运行类似于 sh kill_proc.sh node 这样的命令,并使其执行 kill -9 node。但实际上,我得到的结果是:
kill_process.sh: line 2: User: command not found

我发现当我记录$PROCESS时它是空的。有人知道我做错了什么吗?

2
PROCESS=$LINE | awk '{print $2}' 是错误的。请将其与第一行进行比较。 - Etan Reisner
1
@EtanReisner 如果我尝试 PROCESS=$(LINE | awk '{print $2}'),我仍然会得到一个错误 LINE:找不到命令 - dopatraman
2
你仍然需要在 LINE 前面加上 $ (并将其用 echo 输出到管道中):$(echo $LINE | awk...) - chepner
3
@MarcB,“var=$(command)”这种写法更好。 - clt60
1
使用 killallpkill 而不是自己编写的代码。 - glenn jackman
显示剩余3条评论
2个回答

4
PROCESS=$(echo "$LINE" | awk '{print $2}')

或者

PROCESS=$(ps aux | grep "$1" | awk '{print $2}')

我不知道为什么你会遇到你引用的那个错误,我无法重现它。当你说:

PROCESS=$LINE | awk '{print $2}'

Shell会将其扩展为类似于以下内容:

PROCESS='mayoff  10732 ...' | awk '{print $2}'

为了让示例更易读,我缩短了 $LINE 的值。

管道的第一个子命令设置变量 PROCESS。这个设置变量的命令没有输出,所以 awk 立即读取 EOF 并且什么都不输出。由于管道中的每个子命令在一个子 shell 中运行,因此设置 PROCESS 只会在子 shell 中发生,而在运行脚本的父 shell 中 PROCESS 仍未设置,因此后续命令无法使用它。

(请注意,某些版本的 bash 可以在当前 shell 而不是子 shell 中运行管道的最后一个子命令,但这并不影响此示例。)

你需要运行一个命令将 LINE 的值写入其标准输出,然后将该标准输出连接到 awk 的标准输入,并将结果存储在当前 shell 中的 PROCESS 中。因此,你可以使用 echo 命令(或者像 chepner 在他的答案中指出的那样,使用 printf 命令)实现这一点。


2
你需要使用echo(或printf)来将$LINE的值实际放在awk命令的标准输入上。
LINE=$(ps aux | grep "$1")
PROCESS=$(echo "$LINE" | awk '{print $2}')
echo $PROCESS
kill -9 $PROCESS

不需要使用 LINE,您可以用一行代码设置 PROCESS

PROCESS=$(ps aux | grep "$1" | awk '{print $2}')

或者更好的方法是跳过 grep:
PROCESS=$(ps aux | awk -v pname="$1" '$1 ~ pname {print $2}')

最后,不要使用 kill -9;这只是在调试有问题的程序时的最后一招。对于任何你自己没有编写的程序,kill "$PROCESS" 应该已经足够了。


有点不相关,但是...我无法真正杀死这个进程。我的脚本不再抛出错误,但即使在使用sudo运行时,该进程也没有被杀死。你有什么想法吗? - dopatraman
set -x 放在脚本顶部以更好地了解它正在做什么。该命令会让shell在运行每个命令之前先回显该命令。 - rob mayoff
@dopatraman 显示完整的进程行。STAT字段中包含Z吗?(Z = 僵尸 - 无法终止)。或者,您想要杀死一个等待某些内核I/O的进程。 - clt60
@chepner,“kill“ "$PROCESS" 将杀死一个进程,当 $PROCESS 包含多个 PIDs时怎么办?(例如,grep 找到了更多的进程)...在这种情况下,IMHO 不需要引号。 - clt60
好观点。我很少写这样的代码,其中我会使用一个单一参数来保存我想要按空格分割的一系列值。 - chepner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接