bash - 使用 while 循环迭代参数列表会进入无限循环
问题描述
我将一些日期参数放入脚本中
#!/bin/bash
set -x
today=$(date +%Y%m%d)
while [ ! $# -eq 0 ] #while number of arguments is NOT zero, do this
do
if [[ "$1" = "--test" ]] || [[ "$1" = "-t" ]] ; then
today=$(date +%Y%m%d).test
elif [[ "$1" = "--yesterday" ]] || [[ "$1" = "-y" ]] ; then
DOW=$(date +%u)
if [[ "$DOW" = "1" ]] ; then
today=$(date --date="3 days ago" +%Y%m%d)
else
today=$(date -d "yesterday 13:00" +%Y%m%d)
fi
fi
done
echo "$today"
exit
在 set-x 上,我进入无限循环。它今天永远不会打印。我通过 shellcheck 运行它,它说没问题。
++ '[' '!' 1 -eq 0 ']'
++ [[ --t = \-\-\t\e\s\t ]]
++ [[ --t = \-\t ]]
++ [[ --t = \-\-\y\e\s\t\e\r\d\a\y ]]
++ [[ --t = \-\y ]]
++ '[' '!' 1 -eq 0 ']'
++ [[ --t = \-\-\t\e\s\t ]]
++ [[ --t = \-\t ]]
++ [[ --t = \-\-\y\e\s\t\e\r\d\a\y ]]
++ [[ --t = \-\y ]]
++ '[' '!' 1 -eq 0 ']'
++ [[ --t = \-\-\t\e\s\t ]]
++ [[ --t = \-\t ]]
++ [[ --t = \-\-\y\e\s\t\e\r\d\a\y ]]
++ [[ --t = \-\y ]]
++ '[' '!' 1 -eq 0 ']'
++ [[ --t = \-\-\t\e\s\t ]]
++ [[ --t = \-\t ]]
++ [[ --t = \-\-\y\e\s\t\e\r\d\a\y ]]
++ [[ --t = \-\y ]]
解决方案
是的,不是那么明显,位置参数计数$#
将始终是传递的参数数量,除非您对其进行等效的减量操作,否则循环永远不会退出。
您需要shift
在条件之后使用,else
以便将位置参数移动一,然后循环决定是否还有更多参数需要处理。
您最终进入了这个循环,因为首先使用while
循环来处理参数是一个坏主意,应该使用 for 循环
for arg; do
或传统的 C 风格循环
for ((i=1; i<=$#; i++)); do
为了满足您的while
循环目的,您可以执行以下操作,但不建议这样做。请注意,shift
这是您在导致无限循环的原始帖子中缺少的内容。
while [ -n "$1" ]; do
shift
# Your code logic goes here
done