【问题标题】:Access arguments to Bash script inside a function [duplicate]在函数内访问 Bash 脚本的参数 [重复]
【发布时间】:2018-05-22 17:30:55
【问题描述】:

在函数内部,$1 ... $n 是传递给该函数的参数。 在函数$1 ... $n 之外是传递给脚本的参数。

我能以某种方式访问​​函数内部传递给脚本的参数吗?

【问题讨论】:

    标签: bash


    【解决方案1】:

    感谢您的提示 - 它们启发了我编写调用堆栈函数。我使用'column'命令来美学。

    callstack() {
        local j=0 k prog=$(basename $0)
        for ((i=1; ((i<${#BASH_ARGC[*]})); i++))
        do
            echo -n "${FUNCNAME[$i]/main/$prog} " # function name
            args=""
            for ((k=0; ((k<${BASH_ARGC[$i]})); k++))
            do
                args="${BASH_ARGV[$j]} $args" # arguments
                let j++
            done
            echo -e "$args\t|${BASH_LINENO[$i]}" $(sed -n ${BASH_LINENO[$i]}p "$0" 2>/dev/null) # line calling the function
        done | column -t -s $'\t' -o ' ' | sed 1d # delete callstack entry
    }
    
    compareTemplates Brother_001270_1.jpg |163 compareTemplates "$f" # 处理剩下的 processPdf Brother_001270.pdf |233 文件类型 "${f%[*}" pdf && processPdf "$f" 处理兄弟_001270.pdf |371 --process) shift;处理“$@”;出口 ;; # 处理 jpg 或 pdf sm --quiet --process 兄弟_001270.pdf |0

    【讨论】:

      【解决方案2】:

      正如 Benoit 所说,最简单的解决方案是使用 $@ 将命令行参数作为函数参数传递给函数,然后您可以以与函数外部完全相同的方式引用它们。您实际上将引用传递给函数的值,这些值恰好与命令行参数具有相同的值,请记住这一点。

      请注意,这几乎会阻止您将任何其他参数传递给函数,除非您确切知道将在命令行中传递多少个参数(不太可能,因为这取决于用户并且不受您的约束)

          function fname {
          # do something with $1 $2 $3...$n #
          }
      
          # $@ represents all the arguments passed at the command line #
          fname $@
      

      更好的方法是只传递你知道你将使用的参数,这样你就可以在函数中使用它们,如果你愿意,还可以从你的代码中传递其他参数

          function fname {
          # do something with $1 $count $2 and $3 #
          }
      
          count=1
          fname $1 $count $2 $3
      

      【讨论】:

      • 您可以简单地将固定数量的参数传递给参数列表开头的函数,然后在函数中处理它们后使用shift 跳过它们。 函数调用: fname farg1 farg2 farg3 "$@" 在处理完三个参数后的函数中: shift 3
      • 你也可以调用 fname 告诉它有多少用户参数,使用 $# 允许你不仅在之前指定额外的参数,还可以在之后指定额外的参数:fname beforearg $# "$@" afterarg
      【解决方案3】:

      (我知道这是一篇旧帖子,但没有一个答案真正回答了这个问题。)

      使用 BASH_ARGV 数组。它包含以相反顺序传递给调用脚本的参数(即,它是一个堆栈,顶部在索引 0 处)。您可能必须在shebang(例如#!/bin/bash -O extdebug)或shopt(例如shopt -s extdebug)中打开扩展调试,但它适用于我在bash 4.2_p37中没有打开它。

      来自man bash

      一个数组变量,包含当前 bash 执行调用堆栈中的所有参数。最后一个子程序调用的最后一个参数在栈顶;初始调用的第一个参数位于底部。执行子程序时,提供的参数被推送到 BASH_ARGV。只有在扩展调试模式下,shell 才会设置 BASH_ARGV……。

      这是我用来在一行中按顺序打印所有参数的函数:

      # Print the arguments of the calling script, in order.
      function get_script_args
      {
          # Get the number of arguments passed to this script.
          # (The BASH_ARGV array does not include $0.)
          local n=${#BASH_ARGV[@]}
      
          if (( $n > 0 ))
          then
              # Get the last index of the args in BASH_ARGV.
              local n_index=$(( $n - 1 ))
      
              # Loop through the indexes from largest to smallest.
              for i in $(seq ${n_index} -1 0)
              do
                  # Print a space if necessary.
                  if (( $i < $n_index ))
                  then
                      echo -n ' '
                  fi
      
                  # Print the actual argument.
                  echo -n "${BASH_ARGV[$i]}"
              done
      
              # Print a newline.
              echo
          fi
      }
      

      【讨论】:

      • 很高兴知道。虽然扩展调试听起来有点吓人。
      • function script_args() {for arg in "${BASH_ARGV[@]}";做回声“$arg”;完成| tac }
      【解决方案4】:

      您可以将所有脚本参数存储在一个全局数组中:

      args=("$@")
      

      然后在函数中访问它们:

      f(){
          echo ${args[0]} ${args[1]}
      }
      

      【讨论】:

      • 我认为function f(){ 无效。您应该改用f() {function f {
      • 我已经更正了我的答案,但 function f(){} 确实为我工作。
      【解决方案5】:

      您可能应该使用"$@" 并将其传递到函数参数列表的末尾。在函数内部,shift 在解析您的参数后并像往常一样使用$1$n

      【讨论】:

        【解决方案6】:

        通常你只是在调用时将它们作为参数传递给函数。

        (更丑的)替代方法是将它们放在全局变量中。

        【讨论】:

        • 要使用全局变量方法,如果你的函数是用 export -f 导出的,你只需要 export MY_VAR=$1
        猜你喜欢
        • 2010-10-24
        • 2017-11-29
        • 2013-08-24
        • 1970-01-01
        • 2018-08-08
        • 2019-04-09
        • 1970-01-01
        • 2021-05-24
        相关资源
        最近更新 更多