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

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

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

#!/bin/bash

var=`service httpd configtest`
echo "Output is $var"

根据我的阅读,应该将输出存储在 中var,然后回显它。但是,我运行该脚本时的输出是

Syntax OK
Output is

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

答案1

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

  ....
  apachectl=/usr/sbin/apachectl  
  ....
  graceful|help|configtest|fullstatus)
        $apachectl $@
        RETVAL=$?
        ;;
  ....

做一个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) ---

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

stderr您可以通过重定向到来完成此操作stdout

var=$(service httpd configtest 2>&1)

答案2

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

var=$(service httpd configtest 2>&1)
echo "Output is $var"

或者甚至是这样,没有变量:

echo -n "Output is "
service httpd configtest 2>&1

echo选项-n会抑制末尾的换行符,以便 的输出service httpd configtest位于同一行。

另请注意,我已切换了上面的反引号 ( `...`),$(...)因为反引号可能会导致一些问题,并且通常被认为已弃用。看$(stuff) 和 `stuff` 有什么区别?了解更多信息。

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

答案3

该变量var包含ANSI 转义码这会导致它向上移动一条线。

您的输出可以通过以下示例重现:

var=$'\033[FSyntax OK\n'
echo "Output is $var"

这会产生:

Syntax OK
Output is

其中第一行覆盖脚本的提示符(包含上面两行)。

相关内容