管道命令的Echo输出

4

我正在尝试在我的Bash脚本代码中仅回显一个命令。

OVERRUN_ERRORS="$ifconfig | egrep -i "RX errors" | awk '{print $7}'"
echo ${OVERRUN_ERRORS}

然而,它给了我一个错误并且 $7 没有显示在命令中。我必须将它存储在一个变量中,因为我将在以后的某个时间处理输出(OVERRUN_ERRORS)。做到这一点的正确语法是什么?谢谢。


1
为什么是 $ifconfig - anubhava
1
对于OVERRUN_ERRORS的赋值在当前写法下不执行任何命令(OVERRUN_ERRORS="$ifconfig | egrep -i "RX errors" | awk '{print $7}'")。你真正想做什么?bash -x the-script.sh显示了什么? - Jonathan Leffler
2
顺便问一句 -- 你是从 ifconfig 中提取这个信息的原因是什么,而不是直接从 sysfs 中提取(ifconfig 自己也是从那里得到的)? 直接从源头提取信息更可靠,这样就不用担心 ifconfig 输出格式的未来变化会破坏你的脚本了。 - Charles Duffy
3
同时使用 grepawk 没有必要。awk '/RX errors/ { print $7 }' 可以在一个命令中完成两者的工作。 - Charles Duffy
3个回答

7
关于Bash语法
foo="bar | baz"

...将字符串“bar | baz”分配给名为foo的变量;它不会作为管道运行bar | baz。要做到这一点,您需要使用命令替换,可以使用现代的$()语法或过时的反引号形式:

foo="$(bar | baz)"

关于存储代码以供后续执行

由于问题中意图不明确,

正确的方法是使用函数来存储代码,而将输出存储在字符串中:

# store code in a function; this also works with pipelines
get_rx_errors() { cat /sys/class/net/"$1"/statistics/rx_errors; }

# store result of calling that function in a string
eth0_errors="$(get_rx_errors eth0)"

sleep 1 # wait a second for demonstration purposes, then...

# compare: echoing the stored value, vs calculating a new value
echo "One second ago, the number of rx errors was ${eth0_errors}"
etho "Right now, it is $(get_rx_errors eth0)"

请参阅BashFAQ#50以了解有关将代码存储在字符串中的陷阱及其替代方案的详细讨论。同样相关的是BashFAQ#48,其中详细描述了与eval相关的安全风险,这通常被建议作为解决方法。

关于收集接口错误计数

不要使用ifconfiggrep或者awk来实现,只需要向内核请求你所需的数字即可:

#!/bin/bash
for device in /sys/class/net/*; do
  [[ -e $device/statistics/rx_errors ]] || continue
  rx_errors=$(<"${device}/statistics/rx_errors")
  echo "Number of rx_errors for ${device##*/} is $rx_errors"
done

4
使用$(...)捕获命令的输出,而不是双引号。
overrun_errors=$(ifconfig | egrep -i "RX errors" | awk '{print $7}')

0

你在RX errors周围的双引号是个问题。尝试使用;

OVERRUN_ERRORS="$ifconfig | egrep -i 'RX errors' | awk '{print $7}'"

为了查看命令的执行过程,您可以使用

set -v

或者

set -x

例如:
set -x 
OVERRUN_ERRORS="$ifconfig | egrep -i 'RX errors' | awk '{print $7}'"
set +x

OP在问题中明确表示他们想要命令的输出--也就是说,他们希望该命令实际运行。您在此建议的更改并不能引起这种情况的发生。 - Charles Duffy
如果他们打算执行 eval "$OVERRUN_ERRORS" 而不是 echo "$OVERRUN_ERRORS",我们可能会有一个不同的讨论(但这也将是关于在字符串中存储代码是一种不好的实践的讨论,其中有很多参考资料,如 BashFAQ#50BashFAQ#48)。 - Charles Duffy
@CharlesDuffy,OP写道“我只是想回显一个命令”,并尝试使用echo。他说“$7在命令中没有显示出来”,而不是“没有显示在输出中”。我认为我的解释完全合理。如果他说“我正在尝试运行一个命令”之类的话,我会谈论eval。 - CAB
看标题,“echo output of a piped command” - 就是这些词,按照这个顺序。 - Charles Duffy

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