我正在写一个
的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
但是,如果“what”是包含*
的字符串,例如
myscript emerge -uDN -a whatever/* whatever2 --option
我希望它能够运行
emerge -uDN -a $(eix -u --only-names whatever/*) whatever2 --option
代替。有什么提示吗?
答案 0 :(得分:1)
首先,如果要将*
传递给脚本,则必须阻止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
语句。试一试,如果您有任何问题,请告诉我。
答案 1 :(得分:0)
您提到了命令行:
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
命令,在这种情况下"$@"
确保不会执行任何其他操作。)
使用$@
保留呈现给脚本的参数。如果没有双引号,$*
和"$*"
之间没有区别。在双引号内,"$@"
生成单个字符串,但"${@: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
以确切),而不是依赖shell来执行此操作。正如问题所假设的那样,它还假设$(…)
生成的名称中没有空格。如果有,then
表示法将在空格(或制表符或换行符,......)处拆分名称。
此代码最好作为
中if [[ "${1}" = "emerge" ]]
then
…
fi
子句的主体处理
{{1}}
这比尝试将所有代码压缩到一行更清楚(这可以做到,但没有必要这样做,很多人指出不这样做)。
答案 2 :(得分:-1)
这里有一条线索:
#!/bin/sh
x="bbbccc" # Put different strings in here, and see what happens
case "$x" in
*\**)
echo "Yes"
;;
*)
echo "No"
;;
esac