传递给 bash/ash 函数的参数会发生什么情况?

传递给 bash/ash 函数的参数会发生什么情况?

这个答案是关于——提供了很多关于--在 POSIX shell 中使用的好信息这个关于将所有参数传递给脚本的答案导致以下功能:

my_echo()
{
    set -x
    echo $@ " " \"$@\"
    echo `ps | grep -- "$@" | grep -v grep | awk '{ print $1 }'` 2>/dev/null
    set +x
}

my_echo logread -f

我正在为 OpenWRT 编写这个脚本。灰烬的输出显示

+ echo logread -f   "logread -f"
logread -f   "logread -f"
+ ps
+ grep -v grep
+ awk { print $1 }
+ grep -- logread -f
grep: -f: No such file or directory
+ echo

+ set +x

嗯...我添加到 grep 命令中的引号消失了(logread -f 未加引号)。

我在 bash 中尝试过这个功能

+ echo logread -f ' ' '"logread' '-f"'
logread -f   "logread -f"
++ ps
++ grep --color=auto -- logread -f
++ grep --color=auto -v grep
++ awk '{ print $1 }'
grep: -f: No such file or directory
+ echo

+ set +x

有趣......也许我的论点正在被单独解析?为了验证这个理论,我尝试了:

my_echo "logread -f"

重击输出:

+ echo logread -f ' ' '"logread' '-f"'
logread -f   "logread -f"
++ ps
++ grep --color=auto -- 'logread -f'
++ grep --color=auto -v grep
++ awk '{ print $1 }'
+ echo

+ set +x

echo 命令的输出没有改变(版本set或实际输出,但logread -f现在似乎被视为用双引号引起来。所以......我很幸运,因为我误解了set命令的翻译。但是,我的函数现在工作了。

灰分输出:

+ echo logread -f   "logread -f"
logread -f   "logread -f"
+ ps
+ grep -v grep
+ awk { print $1 }
+ grep -- logread -f
+ echo

+ set +x

现在我得到了我所期望的。事实证明,my_echo使用双引号(单参数)传递的参数运行与

my_echo_new()
{
    echo `ps | grep -- "$1" | grep -v grep | awk '{ print $1 }'` 2>/dev/null
}

my_echo_new "logread -f"

所以……问题似乎出在处理多个参数上。这里发生了什么?这是 ` 的结果还是函数调用的结果还是其他什么?为什么两个地方都需要双引号?

答案1

"$@"扩展到列表带引号的字符串。如果您将两个参数logread和传递-f给您的函数,则将"$@"扩展为字符串。

因此,运行grep -- "$@"将扩展为grep -- logread -f,这意味着“grep forlogread在名为”的文件中-f

您是否想要传递单独的参数而不是单个字符串,然后使用将"$*"参数扩展为单引号字符串。

grep -e "$*"

将扩展到grep -e "logread -f".$IFS使用时,位置参数将由第一个字符分隔"$*"(默认情况下,这是一个空格)。另请注意,使用$*$@ 未引用的没有意义。

顺便说一句,我可能会选择在这里使用pgrep/ pkill

if ! pgrep -xf "$*" >/dev/null; then
    printf 'No process matches "%s" exactly\n' "$*"
fi

相关内容