传递命令行参数,参数
我在写这将传递命令行参数,参数
- 行为不同基于传递的第一个参数一个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
但是,如果认为 “无所谓” 是包含*
一个字符串,如
myscript emerge -uDN -a whatever/* whatever2 --option
我想让它运行
emerge -uDN -a $(eix -u --only-names whatever/*) whatever2 --option
改为。有小费吗?
这里有一个线索:
#!/bin/sh
x="bbbccc" # Put different strings in here, and see what happens
case "$x" in
*\**)
echo "Yes"
;;
*)
echo "No"
;;
esac
你提到的命令行:
myscript emerge -uDN -a whatever/* whatever2 --option
的唯一途径myscript
会看到它的参数列表中的*
是如果没有子目录whatever
下的电流目录,或者它是一个空目录(严格来说:如果它包含任何文件,名称全部以.
开头),并且无论哪种情况,您都没有设置shopt -s nullglob
。如果这些条件不满足,调用myscript
的shell将相应地替换*
(in),并且myscript
将不会看到*
。 (当然,如果你引用的论据 - "whatever/*"
或'whatever/*'
,然后myscript
也会看到*
元字符,不论nullglob
和whatever
子目录的存在或不存在。)
目前尚不清楚是否*
需求只有在遵循-a
选项时才被替换,或者在任何论点中都应该被替换。我会假设所有的论点都需要被取代;如果它只是应该替换的-a
之后的参数,那么它并没有很大的不同。
如果没有代码来处理whatever/*
,命令看起来像:
[[ "${1}" = "emerge" ]] && exec emerge -uDN "${@:2}" || exit 1
差异:
的
exec
是可选的,但保证了emerge
命令后什么都不会被执行(除非emerge
命令无法找到,在这种情况下|| exit 1
确保没有其他执行)。使用
"[email protected]"
来保存呈现给脚本的参数。没有双引号,[email protected]
和$*
之间没有区别。在双引号内,"$*"
会生成单个字符串,但"[email protected]"
会生成传递给脚本的每个参数。"${@: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
将扩展元字符(*
要准确),而不是依靠外壳这样做。正如问题所假设的那样,它还假设eix
生成的名称中没有空格。如果有的话,$(…)
表示法将在空格(或制表符或换行符...)处拆分名称。
该代码会得到更好的为then
条款的身体
if [[ "${1}" = "emerge" ]]
then
…
fi
处理这将是比试图挤压所有的代码成一条线(其可以做的更清晰,但没有指出这样做,许多人指出不这样做)。
首先,如果您打算将*
传递给脚本,则必须防止shell在命令行上进行扩展。最简单的方法是将引用它:
myscript emerge -a 'whatever/*' whatever2 --option
既然你已经在使用[[
操作,注:以下是庆典只有的解决方案,并不能移植到SH。如果要判断$ 3包含*
你可以使用=~
操作:
[[ "${1}" == "emerge" ]] && {
[[ "$3" =~ "*" ]] && \
emerge -uDN $2 $(eix -u --only-names $3) ${*:4} || \
emerge -uDN ${*:2}
}
您也可以重写,如果逻辑变得有点凄惨的复合命令到嵌套if-else
语句。试试看,如果您有任何问题,请告诉我。
这是不可能的,因为Bash甚至在它传递到脚本之前展开'*'。除非你在引号中用''whatever/*“'写出 – user123444555621 2014-09-05 01:18:51
这是可能的,你只需引用你的输入。即'myscript emerge -uDN -a'whatever/*'whatever2 --option'或者变成一团糟。 – 2014-09-05 05:19:50