访问函数内Bash脚本的参数

访问函数内Bash脚本的参数,bash,Bash,在函数中,$1$n是传递给该函数的参数。 函数外部$1$n是传递给脚本的参数 我是否可以访问传递给函数内脚本的参数?通常,您只需在调用时将它们作为参数传递给函数即可 (更丑陋的)替代方法是将它们放入全局变量中。您可能应该使用“$@”并在函数的参数列表末尾传递它。在函数内部,解析参数后,shift,并正常使用$1到$n。您可以将所有脚本参数存储在全局数组中: args=("$@") 然后在函数中访问它们: f(){ echo ${args[0]} ${args[1]} } (我知道这是

在函数中,
$1$n
是传递给该函数的参数。 函数外部<代码>$1$n是传递给脚本的参数


我是否可以访问传递给函数内脚本的参数?

通常,您只需在调用时将它们作为参数传递给函数即可


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

您可能应该使用
“$@”
并在函数的参数列表末尾传递它。在函数内部,解析参数后,
shift
,并正常使用
$1
$n

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

args=("$@")
然后在函数中访问它们:

f(){
    echo ${args[0]} ${args[1]}
}
(我知道这是一篇老文章,但没有一个答案真正回答了这个问题。)

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

manbash

包含当前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
}
#按顺序打印调用脚本的参数。
函数get\u script\u args
{
#获取传递到此脚本的参数数。
#(BASH_ARGV数组不包括$0。)
本地n=${BASH#u ARGV[@]}
如果($n>0))
然后
#获取BASH_ARGV中args的最后一个索引。
本地n_指数=$($n-1))
#从最大到最小遍历索引。
对于$中的i(seq${n_index}-10)
做
#如有必要,请打印一个空格。
如果($i<$n_指数))
然后
回声-n“
fi
#打印实际参数。
echo-n“${BASH_ARGV[$i]}”
完成
#打印换行符。
回声
fi
}

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

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

i、 e

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

i、 e


感谢这些提示——它们启发我编写了一个调用堆栈函数。我在美学上使用了“列”命令

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
}
callstack(){
本地j=0 k prog=$(basename$0)

对于((i=1;((iI)我认为
函数f(){
无效。您应该使用
f(){
函数f{
。我已经更正了我的答案,但是
函数f(){}
确实对我有效。很高兴知道。尽管扩展调试听起来有点可怕。函数脚本{BASH_ARGV[@]}中的arg for arg;done | tac}您只需在参数列表的开头向函数传递固定数量的参数,然后在函数中处理这些参数后,使用
shift
跳过它们。函数调用:
fname farg1 farg2 farg3“$@”
在处理三个参数后在函数中:
shift 3
也可以调用fname,告诉它有多少个用户参数使用$#;这样不仅可以在前面指定额外的参数,还可以在后面指定:
fname beforearg$#“$@”afterarg
要使用全局变量方法,如果您的函数是用export-f导出的,则只需导出MY_VAR=$1即可
    function fname {
    # do something with $1 $count $2 and $3 #
    }

    count=1
    fname $1 $count $2 $3
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" # process the rest processPdf brother_001270.pdf |233 filetype "${f%[*}" pdf && processPdf "$f" process brother_001270.pdf |371 --process) shift; process "$@"; exit ;; # process jpg or pdf sm --quiet --process brother_001270.pdf |0