我正在尝试创建一个函数,并相信我找到了一个很好的工作示例,但我不理解其背后的所有逻辑。
更具体地说,在“while”行上,有人可以解释一下测试是什么以及它的作用吗? $# 是什么(# 不是注释字符吗?),-gt 0 参数来自哪里?在 while 手册页中找不到它。
这是示例:
function my_function()
{
while test $# -gt 0
do
$
echo "$1"
shift
done
}
谢谢。
答案1
虽然#
它本身绝对是一条注释,但$#
包含传递给函数的参数数量。
test
是一个程序,可让您执行各种测试,例如,一个数字是否大于另一个数字(如果您的运算符是-gt
;还有许多其他运算符,请参阅man test
)。如果测试成功(在本例中,如果the number of parameters
IS 大于 0),它将返回成功。
该shift
命令丢弃第一个参数。也减少了$#
整个代码可以看作:用一个参数做一些事情(在本例中,将其显示在屏幕上),然后丢弃它;重复直到没有剩余参数。
如果您想查看剩余的所有参数,对调试有用,请检查以下内容$@
答案2
$#
==> 脚本参数传递
test
==>条件评估命令
-gt
==>代表比...更棒
test a -gt b
==> 如果 a 大于 b,则为 true,否则为 false
把它们放在一起:
while test $# -gt 0
==> 当传递的参数更多时(之所以改变是因为shift)
让事情变得棘手的是shift
while 循环体内。
$1
==> 始终代表第一个参数
为了使这一点更具体,假设您正在传递参数a
,b
和c
。
$1
==> 代表a
这是你的第一个参数
通过调用 now shift
,a
已消失,您的参数列表现在已存在b
,c
因此如果您调用$1
now ,b
则它现在是列表中的第一个参数。shift
再次调用您的参数列表现在只是c
,因此$1
是现在c
。再调用shift
一次会使参数列表为空,因此 while 条件将不会成功(因为参数列表不再大于 0,因为它的大小现在为零),这将导致 while 循环终止。
使用shift
和引用当前参数有什么好处$1
?
它使您可以灵活地在脚本中提前不知道脚本中传递了多少个参数,并且无论如何都可以在 while 循环中一一迭代它们,始终引用当前参数,因为$1
这意味着脚本的头部参数列表。通过shift
ing 最终,参数列表将为空,因此使用 while 条件来检查它是否大于零以便终止而不是无限循环非常重要。
答案3
运行以下脚本以了解变量的含义。将脚本另存为somescript.sh
并使用一些输入参数调用脚本。
#!/bin/bash
echo "I display the total parameters passed to this script from commandline"
echo $#
echo "I display all the parameter values"
echo "Input: $@"
echo "I display the first parameter value"
echo "$1"
shift
echo "After shift: $@"
答案4
如果您能原谅我重复一些答案,我想您可能会发现这很有用。
_fn() { set -- "$@" $(cat)
while ${1+:} false ; do
echo "$1" && [ "$1" = "arg2" ] && echo "$1"
$YOUR_CHK
shift
done
}
echo "arg2" | _fn "arg1"
输出
arg1
arg2
arg2
它可以处理 cmd 行参数和stdin
.它仅while
在参数数组中至少保存一个参数时运行循环来检查它们。它确实会丢弃它检查的每个参数,因此其中一部分$YOUR_CHK
应该是以某种方式保存您认为有价值的信息。
_fn
如果其内容是脚本主体,或者是 shell 函数的形式,则其行为会相同。
_fn
处理stdin
- 在这种情况下,通过将其位置参数 shell数组设置为在命令行上传递的所有内容来"arg2" echo
覆盖|pipe
第一行中的- 或- 并且所有内容都通过 吐出。set
$@
"$@"
cat
$(comand substitution)
while _fn's $1
第一个参数是${set+}
我们替换 shell 的内置函数:true
以满足while
循环条件。一旦$1
未设置替换失败,条件就会计算为false
并且while
循环中断。
while
对于循环的每次迭代,如果成功,则_fn() echo
es 的$1
第一个参数&&
(echo
是总是success)[ tests ]
来查看是否$1
等于字符串,"arg2"
&&
如果es再次[ test ]
成功。_fn() echo
$1
$YOUR_CHK
是一个空操作 - 它是一个未设置的变量,在 shell 执行任何代码之前其计算结果为空。
对于循环的每次迭代,while
我们shift
都会去掉$1
第一个参数。所以在迭代 1 中"$@"
看起来像:
arg1 arg2
但在我们shift
第一次之后,它看起来像:
arg2
在我们shift
上次之后,它看起来像:
因此,这让我们再次回到${1+:} false
- 因为$1
现在未设置,外壳将不会替换:true
,而只会false
被评估,这会打破while
循环并结束_fn().