【问题标题】:How to preserve nested command substitutions inside a watch command如何在监视命令中保留嵌套命令替换
【发布时间】:2021-08-11 13:48:16
【问题描述】:

我正在使用一个监视命令,该命令将多个命令串在一起,除了其中一个命令之外,它们都可以工作。即使单独运行它也没有所需的输出。

这是正在运行的 watch 命令。
watch -n 5 echo "$(echo "$(uptime | awk '{print$11}' | sed 's/,//g')/$(nproc)*100" | bc -l | cut -c-5)% overall CPU utilization"

输出显示执行时的 cpu 利用率,但没有更新。
Every 5.0s: echo 4.750% overall CPU utilization

我几乎可以肯定这是一个引用问题,但我一直在阅读并尝试不同的东西,但无法让它发挥作用。
以下是我尝试过的一些不同版本的命令:

在内部命令 sub 上使用单引号

watch -n 5 echo "$(echo '$(uptime | awk '{print$11}' | sed 's/,//g')/$(nproc)*100' | bc -l | cut -c-5)% overall CPU utilization"
Every 5.0s: echo % overall CPU utilization % overall CPU utilization

转义内部命令 sub 上的单引号

watch -n 5 echo "$(echo \'$(uptime | awk '{print$11}' | sed 's/,//g')/$(nproc)*100\' | bc -l | cut -c-5)% overall CPU utilization"
Every 5.0s: echo % overall CPU utilization % overall CPU utilization

在两组命令子上使用单引号,并转义内部集

watch -n 5 echo '$(echo \'$(uptime | awk '{print$11}' | sed 's/,//g')/$(nproc)*100\' | bc -l | cut -c-5)% overall CPU utilization'
-bash: syntax error near unexpected token )'`

在两组命令 sub 上使用单引号(到目前为止最接近所需的输出)

watch -n 5 echo '$(echo '$(uptime | awk '{print$11}' | sed 's/,//g')/$(nproc)*100' | bc -l | cut -c-5)% overall CPU utilization'
Every 5.0s: echo $(echo 0.24/8*100 | bc -l | cut -c-5)% overall CPU utilization 3.000% overall CPU utilization

如果我能确定如何让它每次都重新运行$(uptime | awk '{print$11}' | sed 's/,//g'),那么它应该可以工作。

【问题讨论】:

  • 那些嵌套的echos怎么不简单useless?

标签: bash command-substitution


【解决方案1】:

要跳过必须引用命令,您可以使用

myfunc() {
  insertYourCodeHere
}
export -f myfunc
watch -n5 bash -c myfunc

【讨论】:

    【解决方案2】:

    我不确定watch 部分应该做什么,但您可以通过将所有处理重构为单个 Awk 脚本来大大简化此操作。

    这样的?

    watch -n 5 'uptime | awk -v n="$(nproc)" "{cpu=\$11; gsub(/,/, \"\", cpu); printf \"%0.3f%% overall CPU utilization\\n\", cpu/n*100 }"'
    

    引用有点讨厌;您可能希望将单引号代码保存为脚本,这样您就可以在 Awk 代码周围切换到单引号并去掉反斜杠。

    【讨论】:

    • 我试过了,但它抛出了这个错误:sh: -c: line 0: unexpected EOF while looking for matching "'`sh: -c: line 1: syntax error: unexpected end of file
    • 抱歉,手机打字很草率……现在试试?
    • 当我自己运行它时确实有效(谢谢你),但是当我将它添加到手表中的另一个命令时,有些东西会崩溃。 watch -n 5 "date && 'uptime | awk -v n="$(nproc)" "{cpu=\$11; gsub(/,/, \"\", cpu); printf \"%0.3f%% overall CPU utilization\\n\", cpu/n*100 }"' && echo \"Top 5 processes...\" && ps -Ao pid,ni,pmem,start_time,etime,pcpu,comm --sort=-pcpu | head -n 6"-bash: syntax error near unexpected token /,/,'`
    • 你不能这样嵌套引号;在单引号内移动date && 和其他命令;或者,相反,删除单引号并相应地重构命令。也许还可以阅读单引号和双引号之间的区别。
    • 终于让它工作了。感谢您的帮助。我需要在几十台不时变化的服务器上运行它,所以我不想走脚本或函数路线。
    猜你喜欢
    • 2017-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-09
    • 1970-01-01
    • 2017-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多