bash函数使用命令,管道和变量处理参数

Chr*_*isJ 2 bash function parameter-passing

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

#!/bin/bash

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

CMD "ntpq -pn | awk '{ printf "%s %s\n", $9,$10 }'"
Run Code Online (Sandbox Code Playgroud)

结果我得到了

#TST# Tue Aug  4 16:15:50 CEST 2015 CMD: ntpq -pn | awk '{ printf %s
Run Code Online (Sandbox Code Playgroud)

我搜索并尝试了好几个小时的事情,但我得不到完整命令的预期结果.

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

Eta*_*ner 5

首先要做的事情.您无法在字符串中可靠地粘贴复杂命令.有关此问题的讨论,请参阅Bash FAQ 050.

这就是说你的问题比那更"简单".

你的问题是引用没有做你期望的事情.

你期望这个命令:

CMD "ntpq -pn | awk '{ printf "%s %s\n", $9,$10 }'"
Run Code Online (Sandbox Code Playgroud)

由shell解析为:

[CMD] ["ntpq -pn | awk '{ printf "%s %s\n", $9,$10 }'"]
Run Code Online (Sandbox Code Playgroud)

但事实并非如此."内部"引用搞砸了(因为它们不是shell的内部).

shell实际解析了这个:

[CMD] ["ntpq -pn | awk '{ printf "%s] [%s\n", $9,$10 }'"]
Run Code Online (Sandbox Code Playgroud)

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

逃避那些"内在的"双引号,你(几乎)得到你想要的东西:

$ 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 }
Run Code Online (Sandbox Code Playgroud)

对于记录,语法突出显示编辑器会将您的代码粘贴到http://www.shellcheck.net/中.

尽管如此,这仍然不太正确$9并且$10失踪了.那是因为shell在双引号上下文中对它们进行了评估.你也需要逃离$那里以防止:

CMD "ntpq -pn | awk '{ printf \"%s %s\n\", \$9,\$10 }'"
Run Code Online (Sandbox Code Playgroud)

总而言之,我想重申一下,Bash FAQ 050使得这个概念很糟糕(假设您希望在某些时候使用该命令).