我正在尝试在 bash 中编写一个函数来访问脚本命令行参数,但它们被替换为函数的位置参数。如果未显式传入命令行参数,该函数有什么方法可以访问它们?
# Demo function
function stuff {
echo $0 $*
}
# Echo's the name of the script, but no command line arguments
stuff
# Echo's everything I want, but trying to avoid
stuff $*
我正在尝试在 bash 中编写一个函数来访问脚本命令行参数,但它们被替换为函数的位置参数。如果未显式传入命令行参数,该函数有什么方法可以访问它们?
# Demo function
function stuff {
echo $0 $*
}
# Echo's the name of the script, but no command line arguments
stuff
# Echo's everything I want, but trying to avoid
stuff $*
如果你想要你的参数 C 风格(参数数组 + 参数数量),你可以使用$@and $#。
$#给你参数的数量。
$@给你所有的论据。你可以把它变成一个数组args=("$@")。
例如:
args=("$@")
echo $# arguments passed
echo ${args[0]} ${args[1]} ${args[2]}
请注意,这里${args[0]}实际上是第一个参数,而不是脚本的名称。
我对Bash 参考手册的阅读说这些东西是在BASH_ARGV中捕获的,尽管它经常谈论“堆栈”。
#!/bin/bash
shopt -s extdebug
function argv {
for a in ${BASH_ARGV[*]} ; do
echo -n "$a "
done
echo
}
function f {
echo f $1 $2 $3
echo -n f ; argv
}
function g {
echo g $1 $2 $3
echo -n g; argv
f
}
f boo bar baz
g goo gar gaz
保存在f.sh
$ ./f.sh arg0 arg1 arg2
f boo bar baz
fbaz bar boo arg2 arg1 arg0
g goo gar gaz
ggaz gar goo arg2 arg1 arg0
f
fgaz gar goo arg2 arg1 arg0
#!/usr/bin/env bash
echo name of script is $0
echo first argument is $1
echo second argument is $2
echo seventeenth argument is $17
echo number of arguments is $#
编辑:请参阅我对问题的评论
拉维的评论基本上就是答案。函数有自己的参数。如果您希望它们与命令行参数相同,则必须将它们传入。否则,您显然是在调用不带参数的函数。
也就是说,如果您喜欢将命令行参数存储在全局数组中以在其他函数中使用,则可以:
my_function() {
echo "stored arguments:"
for arg in "${commandline_args[@]}"; do
echo " $arg"
done
}
commandline_args=("$@")
my_function
commandline_args您必须通过变量 not $@, $1,等来访问命令行参数$2,但它们是可用的。我不知道有什么方法可以直接分配给参数数组,但是如果有人知道,请赐教!
另外,请注意我使用和引用的方式$@- 这是确保特殊字符(空格)不会被弄乱的方式。
# Save the script arguments
SCRIPT_NAME=$0
ARG_1=$1
ARGS_ALL=$*
function stuff {
# use script args via the variables you saved
# or the function args via $
echo $0 $*
}
# Call the function with arguments
stuff 1 2 3 4
一个人也可以这样做
#!/bin/bash
# script_name function_test.sh
function argument(){
for i in $@;do
echo $i
done;
}
argument $@
现在调用你的脚本
./function_test.sh argument1 argument2
您可以使用 shift 关键字(运算符?)来遍历它们。例子:
#!/bin/bash
function print()
{
while [ $# -gt 0 ]
do
echo "$1"
shift 1
done
}
print "$@"
我这样做:
#! /bin/bash
ORIGARGS="$@"
function init(){
ORIGOPT= "- $ORIGARGS -" # tacs are for sed -E
echo "$ORIGOPT"
}
这是@mcarifio 回复,其中包含几条评论:
#!/bin/bash
shopt -s extdebug
function stuff() {
local argIndex="${#BASH_ARGV[@]}"
while [[ argIndex -gt 0 ]] ; do
argIndex=$((argIndex - 1))
echo -n "${BASH_ARGV[$argIndex]} "
done
echo
}
stuff
我想强调:
shopt -s extdebug很重要。如果没有这个BASH_ARGV数组将是空的,除非你在脚本的顶层部分使用它(这意味着在stuff函数之外)。此处详解:为什么变量BASH_ARGV在函数中的值不同,取决于调用函数前是否使用BASH_ARGV是一个堆栈,因此参数以倒序存储在那里。这就是为什么我减少循环内的索引以便我们以正确的顺序获得参数的原因。${BASH_ARGV[@]}需要在 the和 the周围加上双引号,@而不是作为索引,*以便正确处理带有空格的参数。详细信息:bash 数组 - ${#array_name[*]} 和 ${#array_name[@]} 有什么区别将参数从命令行传递到特定函数的最简单且可能最好的方法是将参数直接包含在函数调用中。
# first you define your function
function func_ImportantPrints() {
printf '%s\n' "$1"
printf '%s\n' "$2"
printf '%s\n' "$3"
}
# then when you make your function call you do this:
func_ImportantPrints "$@"
无论您是将参数发送到 main 还是诸如 func_parseArguments 之类的函数(如前面示例中所示的包含 case 语句的函数)或脚本中的任何函数,这都很有用。