如何读取脚本中命令的输出

TMH*_*TMH 4 shell-script command-substitution

我目前正在学习 Linux 脚本,我可以做的一件事是将命令输出分配给变量。命令service httpd configtest返回Syntax is OK,所以我写了这个。

#!/bin/bash

var=`service httpd configtest`
echo "Output is $var"
Run Code Online (Sandbox Code Playgroud)

从我读过的内容来看,应该将输出存储在 中var,然后回显它。但是,运行该脚本时的输出是

Syntax OK
Output is
Run Code Online (Sandbox Code Playgroud)

我做错了什么?如果有区别的话,我正在使用 CentOS 6.5。

cuo*_*glm 7

当你运行时service httpd configtest,它实际上运行命令apachectl configtest

  ....
  apachectl=/usr/sbin/apachectl  
  ....
  graceful|help|configtest|fullstatus)
        $apachectl $@
        RETVAL=$?
        ;;
  ....
Run Code Online (Sandbox Code Playgroud)

做一个strace

$ strace -f -e trace=write apachectl configtest
Process 22999 attached (waiting for parent)
Process 22999 resumed (parent 22998 ready)
[pid 22999] write(1, "1024\n", 5)       = 5
Process 22999 detached
--- SIGCHLD (Child exited) @ 0 (0) ---
Process 23000 attached (waiting for parent)
Process 23000 resumed (parent 22998 ready)
Process 22998 suspended
[pid 23000] write(2, "Syntax OK\n", 10Syntax OK
) = 10
Process 22998 resumed
Process 23000 detached
--- SIGCHLD (Child exited) @ 0 (0) ---
Run Code Online (Sandbox Code Playgroud)

可以看到,输出Syntax OK被写入stderr,导致输出无法保存到var变量。

您可以通过重定向stderrstdout

var=$(service httpd configtest 2>&1)
Run Code Online (Sandbox Code Playgroud)


Gra*_*eme 5

我的猜测是service httpd configtest输出到stderr而不是stdout. 你可以试试:

var=$(service httpd configtest 2>&1)
echo "Output is $var"
Run Code Online (Sandbox Code Playgroud)

甚至这个,没有变量:

echo -n "Output is "
service httpd configtest 2>&1
Run Code Online (Sandbox Code Playgroud)

-n选项以回声抑制在末尾的换行符,使得的输出service httpd configtest将在同一条线上。

另请注意,我已经`...`$(...)上面切换了反引号 ( ) ,因为反引号会导致一些问题并且通常被认为已弃用。请参阅$(stuff) 和 `stuff` 之间的区别是什么?想要查询更多的信息。

有关什么stdoutstderr是什么以及做什么的更多信息2>&1,请查看有关标准流重定向的 Wikipedia 页面。