在Bash脚本中,如何使用变量来设置多个命令选项?

时间:2018-03-12 13:07:03

标签: bash shell string-interpolation

我想在bash中将任意命令的选项存储为字符串,以便我可以这样做。

presets_A='-A'
presets_B='-A -l -F'
ls $presets_A
ls $presets_B

第一个起作用,socond给出ls: invalid option -- ' '

当我尝试将整个命令存储在字符串变量中时(与函数相对),也会发生同样的情况 或别名,这不是我想要的):

presets_A='ls -A'
presets_B='ls -A -l -F'
$presets_A
$presets_B

这会给ls -A: command not found。不好。显然,我还没有找到正确的武断 混合了$%"(@]}"引用和巴什是如此着名的parens。 ${!presets_A}也没有用 但我很可能感到困惑和混乱。

编辑为了澄清,我知道如何使用函数来封装设置选项并在单个命令下包含一堆参数化调用。我正在寻找的东西相当于(Bash)foo "$@"或(Python)foo( *P, **Q )或JS foo( ...P ),这样我就可以获得一个包含参数的可序列化和可传输的值在一个地方打电话。

2 个答案:

答案 0 :(得分:2)

如果函数确实没有按照您的意愿执行,那么您可以使用数组来分隔参数:

presets_A=( -A )
presets_B=( "${presets_A[@]}" -l -F ) # or just -A -l -F

ls "${presets_A[@]}" # ls -A
ls "${presets_B[@]}" # ls -A -l -F

使用"${array[@]}"将数组扩展为参数列表,由字段分隔符(默认为空格)分隔。

但我会考虑只定义两个函数

la () {
  ls -A
}

lalf () {
  ls -A -l -F
}

答案 1 :(得分:0)

我找到了麻烦的来源;我曾尝试在带有此标题的脚本中使用变量作为选项:

#!/usr/bin/env bash
set -euo pipefail; IFS=$'\n\t'

presets_A='-A'
presets_B='-A -l -F'
ls $presets_A
ls $presets_B

当我删除内部字段分隔符设置时,它确实按预期工作,因此我认为我的问题的正确答案是:

"在Bash中存储多个命令参数在Bash中是正常的,并且只要IFS未被重置为空格以外的其他内容就应该有效。"

我可以肯定

#!/usr/bin/env bash
set -euo pipefail; IFS=$' '

presets_A='-A'
presets_B='-A -l -F'
command_C='ls -A -l -F'
ls $presets_A
echo '----------------------------------'
ls $presets_B
echo '----------------------------------'
$command_C

按预期工作;感谢@TomFenech指出那么多(注意顶部附近的显式IFS=' ')。

FWIW我重新设置IFS的原因是quite a few recommendations to do so out there;他们称之为Bash严格模式'。事实证明它会使你的脚本以微妙的方式不兼容。