将grep的结果保存到变量中

She*_*bes 1 bash grep

我有以下命令:

pvs /dev/sdb | grep failed
Run Code Online (Sandbox Code Playgroud)

结果是例如:

/dev/sdb: read failed after 0 of 4096 at 0: Input/output error
/dev/sdb: read failed after 0 of 4096 at 1073676288: Input/output error
/dev/sdb: read failed after 0 of 4096 at 1073733632: Input/output error
/dev/sdb: read failed after 0 of 4096 at 4096: Input/output error
Run Code Online (Sandbox Code Playgroud)

现在我想将结果保存到变量:

STATUS=`pvs /dev/sdb | grep failed`
Run Code Online (Sandbox Code Playgroud)

但是,当我阅读内容时,它是空的:

echo $STATUS
Run Code Online (Sandbox Code Playgroud)

我尝试将其重定向到一个文件:

`pvs /dev/sdb | grep failed` > /tmp/hdd-status
Run Code Online (Sandbox Code Playgroud)

同样的结果,文件仍然是空的.

fed*_*qui 5

这是因为你所看到的东西来自于stderr你所捕捉到的东西stdin。

只需将 stderr 重定向到 stdin,如下所示:

2>&1
Run Code Online (Sandbox Code Playgroud)

这样你的变量定义如下:

STATUS=$(pvs /dev/sdb 2>&1 | grep failed)
Run Code Online (Sandbox Code Playgroud)

另请注意,我使用的$()语法通常优于 ``。基本上,因为它允许您嵌套它们。


看另一个例子:

我们ls有两个文件:a和hello. 首先存在但hello不存在:

$ ls a hello
ls: cannot access hello: No such file or directory
a
Run Code Online (Sandbox Code Playgroud)

我们存储输出:

$ v=$(ls a hello)
ls: cannot access hello: No such file or directory
Run Code Online (Sandbox Code Playgroud)

并且错误不会被存储:

$ echo "$v"
a
Run Code Online (Sandbox Code Playgroud)

但如果我们重定向:

$ v=$(ls a hello 2>&1)
$ echo "$v"
ls: cannot access hello: No such file or directory
a
Run Code Online (Sandbox Code Playgroud)


0xd*_*eef 5

您看到的消息似乎是标准错误消息,而不是标准输出.你可以阅读更多有关重定向这里.

因此,你需要合并STDERR与STDOUT输出管道之前grep:

STATUS=`pvs /dev/sdb 2>&1 | grep failed`
Run Code Online (Sandbox Code Playgroud)

此外,另一种形式的命令替换而不是使用反引号更具可读性:

STATUS=$(pvs /dev/sdb 2>&1 | grep failed)
Run Code Online (Sandbox Code Playgroud)

当使用旧式反引号形式的替换时,反斜杠保留其字面含义,除非后跟$,`或\.第一个不带反斜杠的反引号会终止命令替换.使用$(命令)表单时,括号之间的所有字符组成命令; 没有人特别对待.