这个答案是关于——提供了很多关于--
在 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