【问题标题】:bash function handling of parameter with commands, pipe and variables使用命令、管道和变量处理参数的 bash 函数
【发布时间】:2015-10-27 00:19:50
【问题描述】:

我尝试将包含命令、管道和变量的参数传递给函数。

#!/bin/bash

CMD()
{
    echo "#TST# `date` CMD: $1"
}

CMD "ntpq -pn | awk '{ printf "%s %s\n", $9,$10 }'"

结果我得到了

#TST# Tue Aug  4 16:15:50 CEST 2015 CMD: ntpq -pn | awk '{ printf %s

我搜索并尝试了几个小时,但我没有得到完整命令的预期结果。

如何使用命令、管道和变量处理这样的参数?

【问题讨论】:

  • 您想将命令传递给CMD,还是命令的结果?如果是后者,只需使用CMD "$(ntpq -pn | awk '...')"

标签: bash function parameter-passing


【解决方案1】:

首先要做的事情。您不能可靠地将复杂的命令粘贴到字符串中。有关此问题的讨论,请参阅 Bash FAQ 050

话虽如此,您的问题比那“更简单”。

您的问题是引用没有按照您的预期行事。

你期望这个命令:

CMD "ntpq -pn | awk '{ printf "%s %s\n", $9,$10 }'"

被shell解析为:

[CMD] ["ntpq -pn | awk '{ printf "%s %s\n", $9,$10 }'"]

但事实并非如此。 “内部”引号搞砸了(因为它们不是外壳的内部)。

shell 实际上会解析这个:

[CMD] ["ntpq -pn | awk '{ printf "%s] [%s\n", $9,$10 }'"]

所以CMD 得到两个 参数而不是一个,因此当您尝试在CMD 函数中打印出$1 时遇到问题。

转义那些“内部”双引号,你(几乎)得到你想要的:

$ CMD "ntpq -pn | awk '{ printf \"%s %s\n\", $9,$10 }'"
#TST# Tue Aug  4 10:28:24 EDT 2015 CMD: ntpq -pn | awk '{ printf "%s %s\n", ,0 }

为了记录,语法高亮编辑器会提示您这一点,就像将您的代码粘贴到 http://www.shellcheck.net/ 一样。

虽然$9$10 失踪了,但这仍然不太正确。那是因为 shell 在双引号上下文中对它们进行了评估。您还需要在那里转义 $ 以防止这种情况发生:

CMD "ntpq -pn | awk '{ printf \"%s %s\n\", \$9,\$10 }'"

话虽如此,我想重申Bash FAQ 050 使这是一个糟糕的一般想法(假设您希望在某些时候使用该命令)。

【讨论】:

  • 非常感谢您的信息。我会阅读 BASH 常见问题解答 500。
【解决方案2】:

在调用CMD 时,只需将双引号和$ 符号转义即可。

改变

CMD "ntpq -pn | awk '{ printf "%s %s\n", $9,$10 }'"

CMD "ntpq -pn | awk '{ printf \"%s %s\n\", \$9,\$10 }'"

注意:不这样做也会扩展变量。请参阅 bash 报价单上的 this link

【讨论】:

  • 非常感谢您的信息。我将阅读 bash wiki 的这一部分。
  • 很好地了解$9$10
猜你喜欢
  • 2018-03-20
  • 2019-03-26
  • 1970-01-01
  • 2022-11-04
  • 2010-12-03
  • 2021-02-04
  • 2016-06-18
  • 2012-04-16
  • 2012-03-27
相关资源
最近更新 更多