从命令行调用 Bash 脚本变量
Calling a Bash script variable from the commandline
我有一个接受命令行参数的 Bash 脚本。该脚本定义了几个字符串数组。该参数确定我要打印哪个数组。由于有许多不同的可能数组集可供选择,我希望能够在命令行上准确指定要打印的数组。
例如,假设我定义了这些数组:
#/bin/bash
myarray1=(abc 123)
myarray2=(def 456)
myarray3=(ghi 789)
myarray4=(jkl 012)
myarray5=(mno 345)
myarray6=(pqr 678)
myarray7=(stu 901)
我想从命令行中选择是否要打印所有数组,或者这些数组的各种组合,例如 myarray1
、myarray3
和 myarray4
。但是在另一个 运行 上,我只想打印 myarray5
和 myarray7
.
理想情况下,我希望能够 运行 像这样的脚本:
np ~/usr-bin > bash myscript.bash myarray1 myarray3 myarray4
所以输出是这样的:
abc 123
ghi 789
jkl 012
或者像这样:
np ~/usr-bin > bash myscript.bash myarray5 myarray7
所以输出是这样的:
mno 345
stu 901
我想 Bash 接受这些参数并识别它们是 array/variable 名称,然后像我这样做一样打印它们:echo
我之前几乎没有编写过任何 Bash 脚本,而且我尝试使用的方法似乎不起作用。这是可能的,还是有比我尝试的方法更好的方法来实现这一点?
您可以使用 !
:
为变量扩展引入一个间接级别
#/bin/bash
myarray1=(abc 123)
myarray2=(def 456)
myarray3=(ghi 789)
myarray4=(jkl 012)
myarray5=(mno 345)
myarray6=(pqr 678)
myarray7=(stu 901)
for i in $*; do
echo ${!i}
done
运行 使用 testscript myarray6 myarray2
将输出:
pqr
def
如果你想确保它不会为不存在的变量提供空行,你可以使用:
#/bin/bash
myarray1=(abc 123)
myarray2=(def 456)
myarray3=(ghi 789)
myarray4=(jkl 012)
myarray5=(mno 345)
myarray6=(pqr 678)
myarray7=(stu 901)
for i in $*; do
if [[ ! -z "${!i}" ]]; then
echo ${!i}
fi
done
运行 testscript myarray6 xyzzy_plugh myarray2
将 仍然 输出:
pqr
def
(假设您没有名为 xyzzy_plugh
的环境变量,但是,除非您是 Colossal Caves 的粉丝,否则为什么要这么做?)。
从 Bash 4.3 (2014-02-26) 开始,您可以使用 namerefs 作为简单的解决方案:
print_arrays() {
for a in "$@"; do
# This makes _t_ an alias for the variable whose name is $a
declare -n _t_="$a"
echo "${_t_[@]}"
done
}
4.3之前,需要使用!
间接语法。但是,间接通过的变量需要包含整个数组引用,包括下标。而且您只能通过变量间接访问,而不是字符串表达式。所以你需要做这样的事情:
print_arrays() {
for a in "$@"; do
# Construct the "name", which is the subscripted array name
_t_=${a}[@]
echo "${!_t_}"
done
}
如果您是 Bash 的新手,您应该阅读 Bash manual section on arrays,其中解释了奇怪的语法 "${array[@]}"
。此处 _t_
的定义旨在创建该语法;它本身不是下标表达式。
我有一个接受命令行参数的 Bash 脚本。该脚本定义了几个字符串数组。该参数确定我要打印哪个数组。由于有许多不同的可能数组集可供选择,我希望能够在命令行上准确指定要打印的数组。
例如,假设我定义了这些数组:
#/bin/bash
myarray1=(abc 123)
myarray2=(def 456)
myarray3=(ghi 789)
myarray4=(jkl 012)
myarray5=(mno 345)
myarray6=(pqr 678)
myarray7=(stu 901)
我想从命令行中选择是否要打印所有数组,或者这些数组的各种组合,例如 myarray1
、myarray3
和 myarray4
。但是在另一个 运行 上,我只想打印 myarray5
和 myarray7
.
理想情况下,我希望能够 运行 像这样的脚本:
np ~/usr-bin > bash myscript.bash myarray1 myarray3 myarray4
所以输出是这样的:
abc 123
ghi 789
jkl 012
或者像这样:
np ~/usr-bin > bash myscript.bash myarray5 myarray7
所以输出是这样的:
mno 345
stu 901
我想 Bash 接受这些参数并识别它们是 array/variable 名称,然后像我这样做一样打印它们:echo
我之前几乎没有编写过任何 Bash 脚本,而且我尝试使用的方法似乎不起作用。这是可能的,还是有比我尝试的方法更好的方法来实现这一点?
您可以使用 !
:
#/bin/bash
myarray1=(abc 123)
myarray2=(def 456)
myarray3=(ghi 789)
myarray4=(jkl 012)
myarray5=(mno 345)
myarray6=(pqr 678)
myarray7=(stu 901)
for i in $*; do
echo ${!i}
done
运行 使用 testscript myarray6 myarray2
将输出:
pqr
def
如果你想确保它不会为不存在的变量提供空行,你可以使用:
#/bin/bash
myarray1=(abc 123)
myarray2=(def 456)
myarray3=(ghi 789)
myarray4=(jkl 012)
myarray5=(mno 345)
myarray6=(pqr 678)
myarray7=(stu 901)
for i in $*; do
if [[ ! -z "${!i}" ]]; then
echo ${!i}
fi
done
运行 testscript myarray6 xyzzy_plugh myarray2
将 仍然 输出:
pqr
def
(假设您没有名为 xyzzy_plugh
的环境变量,但是,除非您是 Colossal Caves 的粉丝,否则为什么要这么做?)。
从 Bash 4.3 (2014-02-26) 开始,您可以使用 namerefs 作为简单的解决方案:
print_arrays() {
for a in "$@"; do
# This makes _t_ an alias for the variable whose name is $a
declare -n _t_="$a"
echo "${_t_[@]}"
done
}
4.3之前,需要使用!
间接语法。但是,间接通过的变量需要包含整个数组引用,包括下标。而且您只能通过变量间接访问,而不是字符串表达式。所以你需要做这样的事情:
print_arrays() {
for a in "$@"; do
# Construct the "name", which is the subscripted array name
_t_=${a}[@]
echo "${!_t_}"
done
}
如果您是 Bash 的新手,您应该阅读 Bash manual section on arrays,其中解释了奇怪的语法 "${array[@]}"
。此处 _t_
的定义旨在创建该语法;它本身不是下标表达式。