【问题标题】:How to access command line arguments of the caller inside a function?如何访问函数内调用者的命令行参数?
【发布时间】:2011-02-14 00:23:48
【问题描述】:

我正在尝试在 bash 中编写一个可以访问脚本命令行参数的函数,但它们被替换为函数的位置参数。如果没有显式传入,函数有什么方法可以访问命令行参数?

# Demo function
function stuff {
  echo $0 $*
}

# Echo's the name of the script, but no command line arguments
stuff

# Echo's everything I want, but trying to avoid
stuff $*

【问题讨论】:

  • 我有点困惑,你想要 args 而不传递它们?
  • 是的,关键是从函数内部获取命令行参数,而不将它们作为函数参数传递。它与错误处理情况有关,在这种情况下,我想根据命令行参数进行错误处理,而与传递给函数的参数无关。
  • 仅供参考,$* 非常有问题——它会将./yourScript "first argument" "second argument" 更改为./yourscript "first" "argument" "second" "argument",或者将./yourscript '*.txt' 更改为./yourscript one.txt two.txt 之类的东西,尽管有引号。

标签: bash command-line-arguments argv


【解决方案1】:
#!/usr/bin/env bash

echo name of script is $0
echo first argument is $1
echo second argument is $2
echo seventeenth argument is $17
echo number of arguments is $#

编辑:请参阅我对问题的评论

【讨论】:

    【解决方案2】:

    如果您想使用 C 风格的参数(参数数组 + 参数数量),您可以使用 $@$#

    $# 为您提供参数的数量。
    $@ 为您提供所有参数。你可以通过args=("$@")把它变成一个数组。

    例如:

    args=("$@")
    echo $# arguments passed
    echo ${args[0]} ${args[1]} ${args[2]}
    

    请注意,这里的${args[0]} 实际上是第一个参数,而不是脚本的名称。

    【讨论】:

    • 这并没有解决这个问题——它是在询问将命令行参数传递给一个 shell 函数。
    • @Jefromi,实际上,它完美地回答了这个问题。你可以在函数内部使用args 数组,前提是你事先按照描述对其进行了初始化。
    • 我发现这比遍历 args 要干净得多。
    • 这个简单易行。很好的答案。您在 7 多年前发布了此内容,因此您好,来自未来:2017 年 7 月
    • 更好的是引用echo "${args[0]} ${args[1]} ${args[2]}",或者参数受文件名扩展的影响。
    【解决方案3】:
    # Save the script arguments
    SCRIPT_NAME=$0
    ARG_1=$1
    ARGS_ALL=$*
    
    function stuff {
      # use script args via the variables you saved
      # or the function args via $
      echo $0 $*
    } 
    
    
    # Call the function with arguments
    stuff 1 2 3 4
    

    【讨论】:

      【解决方案4】:

      Ravi 的评论基本上就是答案。函数有自己的参数。如果您希望它们与命令行参数相同,则必须将它们传入。否则,您显然是在调用不带参数的函数。

      也就是说,如果您愿意将命令行参数存储在全局数组中以在其他函数中使用,则可以:

      my_function() {
          echo "stored arguments:"
          for arg in "${commandline_args[@]}"; do
              echo "    $arg"
          done
      }
      
      commandline_args=("$@")
      
      my_function
      

      您必须通过commandline_args 变量而不是$@$1$2 等来访问命令行参数,但它们是可用的。我不知道有什么方法可以直接分配给参数数组,但是如果有人知道,请赐教!

      另外,请注意我使用和引用 $@ 的方式 - 这样可以确保特殊字符(空格)不会被混淆。

      【讨论】:

        【解决方案5】:

        我对@9​​87654321@ 的阅读说这些东西被捕获在BASH_ARGV 中, 尽管它经常谈论“堆栈”。

        #!/bin/bash
        
        shopt -s extdebug
        
        function argv {
          for a in ${BASH_ARGV[*]} ; do
            echo -n "$a "
          done
          echo
        }
        
        function f {
          echo f $1 $2 $3
          echo -n f ; argv
        }
        
        function g {
          echo g $1 $2 $3
          echo -n g; argv
          f
        }
        
        f boo bar baz
        g goo gar gaz
        

        保存在f.sh

        $ ./f.sh arg0 arg1 arg2
        f boo bar baz
        fbaz bar boo arg2 arg1 arg0
        g goo gar gaz
        ggaz gar goo arg2 arg1 arg0
        f
        fgaz gar goo arg2 arg1 arg0
        

        【讨论】:

        • 请注意,像这样迭代数组会导致参数与命令行的顺序相反。
        • ${BASH_ARGV[*]} 应该是"${BASH_ARGV[@]}" 带双引号和@
        【解决方案6】:

        您可以使用 shift 关键字(运算符?)来遍历它们。 示例:

        #!/bin/bash
        function print()
        {
            while [ $# -gt 0 ]
            do
                echo "$1"
                shift 1
            done
        }
        print "$@"
        

        【讨论】:

        • function print() { 是两种不同的函数声明形式之间的混合体——function print {,这是 bash 支持向后兼容 pre-POSIX(也就是说,1991 年之前)的遗留 ksh 语法) ksh 和print() {,这是 POSIX 标准化的。考虑使用一种或另一种来与其他 shell 更广泛地兼容;另见wiki.bash-hackers.org/scripting/obsolete
        【解决方案7】:

        这样也可以

        #!/bin/bash
        # script_name function_test.sh
        function argument(){
        for i in $@;do
            echo $i
        done;
        }
        argument $@
        

        现在调用你的脚本

        ./function_test.sh argument1 argument2
        

        【讨论】:

        • function print() { 是两种不同的函数声明形式之间的混合体——function print {,这是 bash 支持向后兼容 pre-POSIX(也就是说,1991 年之前)的遗留 ksh 语法) ksh 和print() {,这是 POSIX 标准化的。考虑使用一种或另一种来与其他 shell 更广泛地兼容;另见wiki.bash-hackers.org/scripting/obsolete
        【解决方案8】:

        我是这样做的:

        #! /bin/bash
        
        ORIGARGS="$@"
        
        function init(){   
          ORIGOPT= "- $ORIGARGS -" # tacs are for sed -E 
          echo "$ORIGOPT"
        }
        

        【讨论】:

          【解决方案9】:

          将参数从命令行传递到特定函数的最简单且可能最好的方法是将参数直接包含在函数调用中。

          # first you define your function 
          function func_ImportantPrints() {
              printf '%s\n' "$1" 
              printf '%s\n' "$2" 
              printf '%s\n' "$3" 
          } 
          # then when you make your function call you do this:  
          func_ImportantPrints "$@" 
          

          无论您是将参数发送到 main 还是某些函数(如 func_parseArguments(如前面示例中所示包含 case 语句的函数)或脚本中的任何函数),这都很有用。

          【讨论】:

            【解决方案10】:

            这是包含多个 cmets 的 @mcarifio 响应:

            #!/bin/bash
            
            shopt -s extdebug
            
            function stuff() {
              local argIndex="${#BASH_ARGV[@]}"
              while [[ argIndex -gt 0 ]] ; do
                argIndex=$((argIndex - 1))
                echo -n "${BASH_ARGV[$argIndex]} "
              done
              echo
            }
            
            stuff
            

            我想强调一下:

            【讨论】:

              猜你喜欢
              • 2017-05-24
              • 2022-01-19
              • 1970-01-01
              • 2015-01-17
              • 2015-08-20
              • 2017-09-08
              • 1970-01-01
              相关资源
              最近更新 更多