在bash中使用内联if语句添加命令参数

时间:2015-02-23 16:31:22

标签: bash

只有当变量求值为某个值时,我才想在bash中为命令添加一个参数。例如,这有效:

test=1
if [ "${test}" == 1 ]; then
    ls -la -R
else
    ls -R   
fi

这种方法的问题在于,当ls -Rtest时,我必须复制1,否则就是其他内容。我更愿意,如果我可以在一行中写这个,比如这个(伪代码不起作用):

ls (if ${test} == 1 then -la) -R

我尝试了以下但是不起作用:

test=1
ls `if [ $test -eq 1 ]; then -la; fi` -R

这给了我以下错误:

./test.sh: line 3: -la: command not found

3 个答案:

答案 0 :(得分:19)

更为惯用的svlasov's answer版本:

ls $( (( test == 1 )) && printf %s '-la' ) -R

由于echo自己了解一些选项,因此使用printf %s确保要打印的文字不会被误认为选项更安全。
请注意,命令替换不得在这里引用 - 这在当前的情况下很好,但是通常需要更强大的方法 - 见下文。

但是,一般来说,强大的方法是在数组 中构建参数并将其作为一个整体传递:

# Build up array of arguments...
args=()
(( test == 1 )) && args+=( '-la' )
args+=( '-R' )

# ... and pass it to `ls`.
ls "${args[@]}"

更新:OP询问如何有条件地添加额外的基于变量的参数以生成ls -R -la "$PWD"。 在这种情况下,数组方法是必须的:每个参数必须成为自己的数组元素,这对于支持可能嵌入空格的参数至关重要:

(( test == 1 )) && args+= ( '-la' "$PWD" ) # Add each argument as its own array element.

至于为什么你的命令,

 ls `if [ $test -eq 1 ]; then -la; fi` -R

没有工作:

反引号之间的命令(或其现代的,可嵌套的等价物,$(...)) - 一个所谓的command substitution - 就像执行任何其他shell命令一样执行(尽管在 sub -shell)并将整个构造替换为命令的 stdout 输出。

因此,您的命令会尝试执行字符串-la,但失败了。要将其发送到 stdout ,根据需要,您必须使用echoprintf等命令。

答案 1 :(得分:5)

使用echo

打印参数
test=1
ls `if [ $test -eq 1 ]; then echo "-la"; fi` -R

答案 2 :(得分:2)

另一个没有使用eval并使用BASH数组的答案:

myls() { local arr=(ls); [[ $1 -eq 1 ]] && arr+=(-la); arr+=(-R); "${arr[@]}"; }

将其用作:

myls
myls "$test"

此脚本在数组arr中构建整个命令,并保留命令选项的原始顺序。