【问题标题】:How do i store the output of a bash command in a variable? [duplicate]如何将 bash 命令的输出存储在变量中? [复制]
【发布时间】:2014-10-21 12:56:22
【问题描述】:

我正在尝试编写一个简单的脚本来杀死一个进程。我已经阅读了Find and kill a process in one line using bash and regex,所以请不要将我重定向到那个。

这是我的代码:

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 时它是空的。 有谁知道我做错了什么?

【问题讨论】:

  • PROCESS=$LINE | awk '{print $2}' 是错误的。将其与第一行进行比较。
  • @EtanReisner 如果我尝试PROCESS=$(LINE | awk '{print $2}') 我仍然收到错误LINE: command not found`
  • 您仍然需要将$ 前缀为LINE(并将echo 加入管道):$(echo $LINE | awk...)
  • @MarcB var=$(command) 更好...
  • LINE=$(ps aux | grep '$1') 中,'$1' 没有展开。使用双引号,例如LINE=$(ps aux | grep "$1")

标签: bash shell sh


【解决方案1】:
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 中,而不是在子shell 中设置PROCESS 并且不向awk 提供任何内容。因此,您需要运行一个将LINE 的值写入其标准输出的命令,并将该标准输出连接到awk 的标准输入。 echo 命令可以做到这一点(或 printf 命令,正如 chepner 在他的回答中指出的那样)。

【讨论】:

    【解决方案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 运行该进程也不会被终止。想法?
    • set -x 放在脚本的顶部,以便更好地了解它在做什么。此命令使 shell 在运行之前回显每个命令。
    • @dopatraman 显示完整的生产线。在STAT 字段中包含Z? (Z = 僵尸 - 无法杀死)。或者,您可能想杀死一个等待内核 I/O 的进程。
    • @chepner kill "$PROCESS" 将杀死一个进程,当$PROCESS 将包含多个PIDs? (例如 grep 发现更多进程)......在这种情况下恕我直言,不需要引号。
    • 好点。我很少编写代码,我会使用单个参数来保存一系列我想在空格上分割的值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-03
    • 1970-01-01
    • 2015-03-10
    • 2011-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多