在函数内部复制命令行参数

时间:2017-05-28 20:36:11

标签: bash

目前正在开发以下版本的Bash:

GNU bash, version 4.2.46(1)-release (x86_64-redhat-linux-gnu)

我目前的剧本:

#!/usr/bin/env bash

function main() {
  local commands=$@
  for command in ${commands[@]} ; do
    echo "command arg: $command"
  done
}

if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
  set -e
  main $@
fi

简单来说,如果脚本被调用,这个脚本只会执行main,类似于Python的if __name__ == '__main__'约定。

main函数中,我只是循环遍历所有命令变量,但引用转义并不是按预期发生的:

$ tests/simple /bin/bash -c 'echo true'
command arg: /bin/bash
command arg: -c
command arg: echo
command arg: true

这里的最后一个参数应该被Bash解析为一个单独的参数,然而它被分成单个的单词。

我做错了什么?我希望echo true显示为一个参数。

3 个答案:

答案 0 :(得分:2)

除了正在进行单词分割的'echo true'部分之外,您获得了正确的输出。您需要在代码中使用双引号:

main "$@"

在功能中:

function main() {
  local commands=("$@") # need () and double quotes here
  for command in "${commands[@]}" ; do
    echo "command arg: $command"
  done
}

该函数获取自己的$@副本,因此您不需要制作本地副本。

通过这些更改,我们得到了这个输出:

command arg: /bin/bash
command arg: -c
command arg: echo true

通常,将shell命令存储在变量中并不好。请参阅BashFAQ/050

另见:

答案 1 :(得分:0)

您可能希望做更多类似的事情:

function main() {
    while [ $# -gt 0 ]
    do
        echo "$1"
        shift
    done
}

main /bin/bash -c "echo true"

密钥实际为$#,它计算命令行参数的数量(不包括调用名称$0)。环境变量$#自动设置为命令行参数的数量。如果使用以下命令行调用函数/脚本:

$ main /bin/bash -c "echo true"

$#的价值为" 3"对于参数:" / bin / bash"," -c"和" echo true"。最后一个计为一个参数,因为它们包含在引号内。

  1. shift命令"移位"所有命令行参数左侧一个位置。
  2. 最左边的参数丢失(main)。

答案 2 :(得分:0)

引用@传递给main是你的问题,但我想我会提到你也不需要在main中分配值来使用它。 您可以执行以下操作:

main()
{
  for command
  do
    ...
  done
}

main "$@"