[英]Passing command line parameters in bash, detecting content of parameters
我正在写一个bash脚本
看起来像:
[[ "${1}" = "-h" || "${1}" = "--help" ]] && echo -e "somehelp"
[[ "${1}" = "echo" ]] && echo ${*:2}
[[ "${1}" = "emerge" ]] && emerge -uDN ${*:2}
some-magic-here
现在,如果我这样做
myscript emerge -a whatever whatever2 --option
它会运行
emerge -uDN -a whatever whatever2 --option
但是,如果“ whatever”是包含*
的字符串,例如
myscript emerge -uDN -a whatever/* whatever2 --option
我想要它运行
emerge -uDN -a $(eix -u --only-names whatever/*) whatever2 --option
代替。 有小费吗?
首先,如果要将*
传递给脚本,则必须防止命令行中的Shell进行扩展。 最简单的方法是引用它:
myscript emerge -a 'whatever/*' whatever2 --option
由于您已经在使用[[
运算符, 请注意:以下内容仅适用于bash解决方案,不能移植到sh。 要确定$ 3是否包含*
,可以使用=~
运算符:
[[ "${1}" == "emerge" ]] && {
[[ "$3" =~ "*" ]] && \
emerge -uDN $2 $(eix -u --only-names $3) ${*:4} || \
emerge -uDN ${*:2}
}
如果逻辑有些模糊,您也可以将复合命令重写为嵌套的if-else
语句。 试试看,如果您有任何问题,请告诉我。
您提到了命令行:
myscript emerge -uDN -a whatever/* whatever2 --option
唯一的办法myscript
将看到*
的参数列表,如果没有子目录, whatever
在当前目录下,或者它是一个空目录(严格:如果它包含任何文件,名称都开始用.
),并在任一情况下,您没有设置shopt -s nullglob
。 如果不满足这些条件,则调用myscript
的shell将适当地替换*
,而myscript
将不会看到*
。 (当然,如果您引用参数- "whatever/*"
或'whatever/*'
,则myscript
也将看到*
元字符,而不管nullglob
和whatever
子目录的存在与否。)
目前尚不清楚是否仅在*
跟随-a
选项时才需要替换*
,或者是否应该在任何自变量中替换*。 我将假定所有参数都需要替换; 如果仅应替换-a
之后的参数,则差别不大。
如果没有处理whatever/*
的代码,则命令如下所示:
[[ "${1}" = "emerge" ]] && exec emerge -uDN "${@:2}" || exit 1
区别:
exec
是可选的,但保证在执行emerge
命令之后什么都不会执行(除非找不到emerge
命令,在这种情况下, || exit 1
确保没有其他执行)。
使用"$@"
保留提供给脚本的参数。 没有双引号, $@
和$*
之间没有区别。 在双引号内, "$*"
生成一个字符串,但是"$@"
生成传递给脚本的每个参数。 "${@:2}"
表示法在第二个到最后一个参数之间进行。
要为任何参数处理*
,我们需要检测*
。 如果我们使用数组,这将是最简单的。
数组arglist
将包含要传递给emerge
命令的参数。 我们需要遍历脚本的参数,检查*
:
arglist=( "-uDN" )
for arg in "${@:2}"
do
case "$arg" in
(*\**) arglist+=( $(eix -u --only-names "$arg") );;
(*) arglist+=( "$arg" );;
esac
done
exec emerge "${arglist[@]}"
exit 1
请注意,这是假设eix
会扩展元字符(确切地说是*
),而不是依靠shell来扩展。 正如问题所假设的那样,它还假设eix
生成的名称中没有空格。 如果有的话, $(…)
表示法将在空格(或制表符或换行符,…)处拆分名称。
最好将这段代码作为then
子句的主体进行处理
if [[ "${1}" = "emerge" ]]
then
…
fi
这比尝试将所有代码都压缩到一行中(可以这样做,但这样做没有意义,很多人不这样做)要清楚得多。
这是一个线索:
#!/bin/sh
x="bbbccc" # Put different strings in here, and see what happens
case "$x" in
*\**)
echo "Yes"
;;
*)
echo "No"
;;
esac
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.