使用环境变量将参数传递给命令

Ed *_*d Y 8 bash eval

我正在尝试编写一个 bash 脚本,它接受一个环境变量并将其传递给一个命令。

所以如果我有类似的东西:

export OUT="-a=arg1 -b=\"arg2.0 arg2.1\""
Run Code Online (Sandbox Code Playgroud)

我希望在我的 bash 脚本中执行以下操作:

<command> -a=arg1 '-b=arg2.0 arg2.1'
Run Code Online (Sandbox Code Playgroud)

我有一种方法似乎可以做到这一点,但它涉及使用 eval:

eval <command> ${OUT}
Run Code Online (Sandbox Code Playgroud)

如果我包含set -x正确的命令,我会看到:

+ eval <command> a=arg1 'b="arg2.0' 'arg2.1"'
++ <command> -a=arg1 '-b=arg2.0 arg.1'
Run Code Online (Sandbox Code Playgroud)

但是,我已经探讨了使用 eval 的危险,并且由于这将从用户输入中获取参数,因此不太理想。

由于这是 bash,我还考虑使用数组来存储我的参数并简单地说:<command> "$ARRAY[@]"做我想做的事。我一直在尝试使用 IFS,但我不确定我应该拆分什么。

Klo*_*tho 5

对于上面答案中描述的简化问题;即,将以下环境变量转换为 bash 脚本中的三个参数:

export OPTS="a=arg1 b=arg2.0 b=arg2.1"
Run Code Online (Sandbox Code Playgroud)

只需执行以下操作:

#!/bin/bash
opts=( $OPTS )
my-command "${opts[@]}"

# Use this for debugging:
echo "number of opts = ${#opts[@]}; opts are: ${opts[@]}"
Run Code Online (Sandbox Code Playgroud)


ric*_*ici 4

如果您对 的格式不是完全不灵活$OUT,一种可能是重复该option=字符串以允许连接。然后你会写:

export OUT="a=arg1 b=arg2.0 b=arg2.1"
Run Code Online (Sandbox Code Playgroud)

如果这是可以接受的,以下脚本将起作用

#!/bin/bash

# Parse $OUT into an associative array.
# Instead of using $OUT, it would be cleaner to use "$@".
declare -A args
for arg in $OUT; do
  if [[ "$arg" =~ ^([[:alnum:]]+)=(.*)$ ]]; then
    key=${BASH_REMATCH[1]}
    val=${BASH_REMATCH[2]}
    if [[ -z ${args[$key]} ]]; then
      args[$key]=-$key="$val"
    else
      args[$key]+=" $val"
    fi
  fi
done

# Test, approximately as specified
command() { :; }
set -x
command "${args[@]}"
set +x
Run Code Online (Sandbox Code Playgroud)

我不能说我很喜欢它,但这是我能达到的最接近的。

这是一个示例运行:

$ export OUT="a=foo b=bar  b=glitch s9= s9=* "
./command-runner
+ command -a=foo '-b=bar glitch' '-s9= *'
+ :
+ set +x
Run Code Online (Sandbox Code Playgroud)

如果导入 bash 函数(例如,在 bash 启动文件中),则可以更好地利用数组。这是一种方法:

# This goes into your bash startup file:
declare -a SAVED_ARGS
save_args() {
  SAVED_ARGS=("$@")
}

do_script() {
  /path/to/script.sh "${SAVED_ARGS[@]}" "$@"
}
Run Code Online (Sandbox Code Playgroud)

出于说明目的,script.sh

#!/bin/bash
command() { :; }

set -x
command "${@/#/-}"
set +x
Run Code Online (Sandbox Code Playgroud)

例子:

$ save_args x=3 y="a few words from our sponsor"
$ do_script a=3 b="arg2.0 arg2.1"
+ command -x=3 '-y=a few words from our sponsor' -a=3 '-b=arg2.0 arg2.1'
+ :
+ set +x
$ do_script a=42
+ command -x=3 '-y=a few words from our sponsor' -a=42
+ :
+ set +x
Run Code Online (Sandbox Code Playgroud)

如果不明显:

command() { :; }
Run Code Online (Sandbox Code Playgroud)

定义了一个名为 bash 的函数,它几乎不执行任何操作(除了调用不执行任何操作的command内置函数),并且:

"${@/#/-}"
Run Code Online (Sandbox Code Playgroud)

扩展到位置参数,在每个参数的开头插入破折号,使用查找和替换替换。该模式#实际上是一个空模式,仅匹配字符串的开头。