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

Joh*_*han 11 bash

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

test=1
if [ "${test}" == 1 ]; then
    ls -la -R
else
    ls -R   
fi
Run Code Online (Sandbox Code Playgroud)

这种方法的问题是,我要重复ls -R两当test1,或者如果它是别的东西.我更愿意,如果我可以在一行中写这个,而不是这样(伪代码不起作用):

ls (if ${test} == 1 then -la) -R
Run Code Online (Sandbox Code Playgroud)

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

test=1
ls `if [ $test -eq 1 ]; then -la; fi` -R
Run Code Online (Sandbox Code Playgroud)

这给了我以下错误:

./test.sh: line 3: -la: command not found
Run Code Online (Sandbox Code Playgroud)

mkl*_*nt0 23

一个更惯用的版本的svlasov的答案:

ls $( (( test == 1 )) && printf %s '-la' ) -R
Run Code Online (Sandbox Code Playgroud)

由于echo本身可以理解一些选项,因此使用它printf %s来确保要打印的文本不会被误认为是一个选项更安全.
请注意,此处不得引用命令替换- 这在当前情况下是正常的,但通常需要更强大的方法 - 请参阅下文.

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

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

# ... and pass it to `ls`.
ls "${args[@]}"
Run Code Online (Sandbox Code Playgroud)

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

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

至于为什么你的命令,

 ls `if [ $test -eq 1 ]; then -la; fi` -R
Run Code Online (Sandbox Code Playgroud)

不起作用:

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

因此,您的命令会尝试执行-la失败的字符串.要将其发送到stdout,如此处所需,您必须使用诸如echo或之类的命令printf.

  • 使用 `[[ "$ENV_VARIABLE" == "true" ]] && args+=('-la')`,您可以使用环境变量有条件地检查其值。 (3认同)

svl*_*sov 5

用以下命令打印参数echo

test=1
ls `if [ $test -eq 1 ]; then echo "-la"; fi` -R
Run Code Online (Sandbox Code Playgroud)


Vet*_*sin 5

我不能说这是多么可以接受,但是:

test=1
ls ${test:+'-la'} -R
Run Code Online (Sandbox Code Playgroud)

有关条件真值表,请参阅https://stackoverflow.com/revisions/16753536/1 。

  • 这个和基于数组的答案是唯一两个还不错的答案。 (3认同)