【问题标题】:How to pass the command via getopts argument and execute it?如何通过 getopts 参数传递命令并执行它?
【发布时间】:2019-11-29 00:59:03
【问题描述】:

我正在尝试制作一些应用程序,但在这里描述它太难了,所以我将我的问题简化为更简单的问题。

我只想制作一个带有两个参数的脚本:时间和命令。它使用 getopts 解析参数,等待一段时间并执行给定的命令。

我尝试过使用双引号、单引号和完全不带引号的各种组合,使用 bash 数组(我认为是这样)并寻找类似的问题,但没有帮助。

脚本.sh

time=1
command=""
while getopts "t:x:" opt; do
  case $opt in
    t) time=$OPTARG;;
    x) command=( "$OPTARG" );; # store the command in a variable
  esac
done
sleep $time
"${command[@]}" # execute the stored command

test.sh

# script to test arguments passing
echo "1$1 2$2 3$3 4$4"

脚本的执行结果应该和-x参数中传入的命令的执行结果一致。

$./script.sh -x "./test.sh a 'b c'"
1a 2'b 3c' 4 # actual results
$./test.sh a 'b c'
1a 2b c 3 4 # expected results

【问题讨论】:

  • command="$OPTARG";; ... bash -c "$command" 怎么样?
  • @melpomene 它可以工作并解决我的问题......但是如果没有bash 命令它可以完成吗?
  • 可能涉及到eval

标签: arrays bash command-line-arguments execution getopts


【解决方案1】:

"${command[@]}" 更改为eval "${command[0]}"

【讨论】:

  • 我也会切换到将command 存储为普通变量而不是数组(无论如何你只是使用第一个元素)。
  • 任何时候你宣传使用eval,一只小猫就死了;)
  • 我叫 alf,来自梅尔马克。但你是对的 - 没有 eval 会更好!
【解决方案2】:

没有评估的解决方案:

#!/usr/bin/env bash

time=1
command=""
while getopts "t:x:" opt; do
  case "${opt}" in
    t)
      time="${OPTARG}"
      ;;
    x)
      command="${OPTARG}" # get the command

      # shift out already processed arguments
      shift "$(( OPTIND - 1 ))"
      # and exit the getopts loop, so remaining arguments
      # are passed to the command
      break
      ;;
    *) exit 1 ;; # Unknown option
  esac
done

sleep "${time}"
"${command}" "${@}" # execute the command with its arguments

【讨论】:

  • 但是这个命令将不起作用:./script.sh -x ./test.sh a "b c" -t 10。您的解决方案会将其解释为command="./test.sh a "b c" -t 10"./script.sh -t 10 -x './test.sh a "b c"' 也不起作用。
猜你喜欢
  • 1970-01-01
  • 2021-04-21
  • 2014-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-12
  • 2017-04-14
相关资源
最近更新 更多