访问函数内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