我不理解以下代码中的shift
:
#! /usr/local/bin/bash
# process command line options
interactive=
filename=
while [[ -n $1 ]]; do
case $1 in
-f | --file) shift #don't understand the shift #No.1
filename=$1 ;;
-i | --interactive) interactive=1
;;
-h | --help) usage
exit;;
*) echo "usage >&2 exit 1";;
esac
shift # don't understand the shift #2
done
#interactive mode
if [[ -n $interactive ]]; then
echo "do something"
fi
#output html page
if [[ -n $filename ]]; then
if touch $filename && [[ -f $filename ]]; then
echo "write_html_page > $filename" #debug
else
echo "$program: Cannot write file $filename " >&2
exit 1
fi
else
echo "write_html_page to terminal" # debug
fi
测试
$ bash question.sh -f test
write_html_page > test
$ bash question.sh -f
write_html_page to terminal
当我删除shift
并将filename=$1
更改为filename=$2
$ bash question.sh -f
write_html_page to terminal
# it works properly
$ bash question.sh -f test
usage >&2 exit 1
write_html_page > test
# it almost function nicely except that `usage >&2 exit 1` is executed.
因此shift
无法完全替换为filename=$2
。
如果删除了第二次转移,循环就会无休止地运行。
我可以直观地解释shift
吗?
我没有用其他语言找到这样一个神奇的命令。
答案 0 :(得分:2)
此页面上的示例:
http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_07.html
解释了它在做什么。
编辑:
示例:
当事先不知道命令的参数个数时,通常使用shift语句,例如,当用户可以根据需要提供尽可能多的参数时。在这种情况下,参数通常在while循环中处理,测试条件为(($#))。只要参数的数量大于零,这种情况就成立了。 $ 1变量和shift语句处理每个参数。每次执行移位时参数的数量都会减少,最终变为零,while循环退出。
答案 1 :(得分:2)
shift
将删除第一个位置参数,并将每个其他参数左移一个。
例如,让我们考虑以下事项:
#!/bin/bash
echo "$@"
shift
echo "$@"
shift
echo "$@"
鉴于echo "$@"
将打印所有参数,如果您要运行此参数,则会发生以下情况:
./test.bash 1 2 3 4 5
echo "$@" # prints 1 2 3 4 5
shift # Removes 1 and shifts everything else along
echo "$@" # prints 2 3 4 5
shift # shifting again
echo "$@" # prints 3 4 5
在您的示例中,脚本正在解析所有标志。 -i
和-h
只是开关,不处理以下参数。但是,-f
需要filename
。
第二个shift
将处理标志,移动参数,然后再次处理它们。因此,您可以拥有./program.bash -i -f filename
。 -i
将在第二个班次移动,然后文件名将在下一个循环中处理。
如果您要运行./program.bash -f filename -i
,则filename
需要与-f
一起移动。因此,在-f
的案例块上有一个额外的转移。在此示例中,-f
将在大小写块内移动,然后filename
将移动第二个shift
。然后循环将再次运行以处理任何进一步的标志。
由于while循环是[[ -n $1 ]]
,循环将一直运行,直到没有其他参数。