Til*_*ill 6 shell bash shell-script
我想知道如何$@从另一个函数或另一个脚本文件引用 ,而不需要像getopts所做的那样传递它。非常感谢!
# 上一个问题: bash getopts 如何知道调用有哪些参数
A() {
B
}
B() {
# how to reference the $@ of A here ?
# which will be 1 2 3 4
}
A 1 2 3 4
Run Code Online (Sandbox Code Playgroud)
Sté*_*las 14
如果不以某种方式A提供其位置参数,您就无法做到这一点。B可以通过传递它们:
A() {
B "$@"
}
B() {
[ "$#" -eq 0 ] || printf '<%s>\n' "$@"
}
Run Code Online (Sandbox Code Playgroud)
或者将它们存储在数组中:
A() {
A_args=( "$@" )
B
}
B() {
[ "${#A_args[@]}" -eq 0 ] || printf '<%s>\n' "${A_args[@]}"
}
Run Code Online (Sandbox Code Playgroud)
由于 bash 与 ash/ksh88/zsh(但与 ksh93 或 zsh 的private变量不同)对其局部变量进行动态作用域,您甚至可以将该A_args变量设置local为,A并且它仍然可以在调用的函数中使用A。
bash允许您访问其父作用域的变量,即使它们被当前作用域中的局部变量隐藏unset,通过利用其内置函数的当前错误(在某些情况下不会取消设置,但会显示父作用域中的变量),但是您无法以这种方式从父作用域访问位置参数,因为在 bash 中(与zsh//相反),位置参数无法映射到数组变量rc,fish因为 bash 数组设计是按照 Korn shell 的设计而设计的,而数组则不然真的是数组。
如果您希望某些代码能够访问或修改(通过shift或set)函数的位置参数或本地选项,或者return从函数中访问或修改,则需要该代码在该函数的范围内运行,因此不能在单独的函数中。
您可以使用别名(它们是 C 预处理器宏的 shell 等效项,但它们不能接受参数)或不过eval。
但请注意:
shopt -s expand_aliases.所以你可以这样做:
[ -z "$BASH_VERSION" ] || shopt -s expand_aliases # work around for bash
alias B='{
[ "$#" -eq 0 || printf "<%s>\n" "$@"
shift
}'
A() {
echo "$#"
B
echo "$#"
}
A a b c
Run Code Online (Sandbox Code Playgroud)
或者:
B='
[ "$#" -eq 0 || printf "<%s>\n" "$@"
shift
'
A() {
echo "$#"
eval "$B"
echo "$#"
}
A a b c
Run Code Online (Sandbox Code Playgroud)
实际上,在 bash 中,当启用该选项(通常用于调试器)时,调用堆栈中所有函数的位置参数列表将在包含参数数量的特殊数组extdebug中可用$BASH_ARGV(尽管顺序相反)$BASH_ARGC在每个级别。
但请注意:
bash -O extdebugshopt -s extdebug
shopt -u xpg_echo
A() {
B x y
}
reverse_helper() { caller_args=( "${BASH_ARGV[@]:0:BASH_ARGC}" ); }
B() {
local -a caller_args
local IFS=,
reverse_helper "${BASH_ARGV[@]:BASH_ARGC[0]:BASH_ARGC[1]}"
echo "my args: $*"
echo "my caller args: ${caller_args[*]}"
}
A a b c
Run Code Online (Sandbox Code Playgroud)
这使:
shopt -s extdebug
shopt -u xpg_echo
A() {
B x y
}
reverse_helper() { caller_args=( "${BASH_ARGV[@]:0:BASH_ARGC}" ); }
B() {
local -a caller_args
local IFS=,
reverse_helper "${BASH_ARGV[@]:BASH_ARGC[0]:BASH_ARGC[1]}"
echo "my args: $*"
echo "my caller args: ${caller_args[*]}"
}
A a b c
Run Code Online (Sandbox Code Playgroud)