我在bash脚本中使用此代码。我用它将源文件夹传输到多个目的地:
while(!a){
if(b.b){
throw new Exception("b is true");
}
System.out.println("there is something more to execute");
}
此命令效果很好。我想在脚本的开头设置目的地。所以目的地的数量可能会有所不同。
例如,目的地可以是var或数组:
b.b
有一个很好的方法吗?
答案 0 :(得分:5)
这种情况eval
是更容易的选择之一,但需要非常谨慎地使用它。
unpackInDestinations() {
local dest currArg='' evalStr=''
for dest; do
printf -v currArg '>(cd %q && exec tar xf -)' "$dest"
evalStr+=" $currArg"
done
eval "tee $evalStr >/dev/null"
}
tar cf - SOURCE/ | unpackInDestinations /Volumes/dest{1,2}
效率较低(但也许没有,导致任何人试图审计代码的安全性同样令人惊愕),也可以写一个递归函数:
unpackInDestinations() {
local dest
if (( $# == 0 )); then
cat >/dev/null
elif (( $# == 1 )); then
cd "$1" && tar xf -
else
dest=$1; shift
tee >(cd "$dest" && exec tar xf -) | unpackInDestinations "$@"
fi
}
此创建的tee
的数量因参数的数量而异,因此它的效率远低于手写代码或基于eval
的等效值。
如果你只需要支持新版本的bash(下面要求至少 4.1),那么还有一些额外的魔法可以提供两全其美的效果:
unpackInDestinations() {
local -a dest_fds=( ) args=( )
local arg fd_num retval
# open a file descriptor for each argument
for arg; do
exec {fd_num}> >(cd "$arg" && exec tar xf -)
dest_fds+=( "$fd_num" )
args+=( "/dev/fd/$fd_num" )
done
tee "${args[@]}" >/dev/null; retval=$?
# close the FDs
for fd_num in "${dest_fds[@]}"; do
exec {fd_num}>&-
done
# and return the exit status we got from tee
return "$retval"
}