9.7. shift 内建命令

9.7.1. 它的作用是什么?

shift 命令是 Bash 内建命令之一,也是 Bourne shell 的内建命令。这个命令接受一个参数,一个数字。位置参数会向左移动这个数字 N 位。位置参数从N+1$#被重命名为变量名,从$1$# - N+1.

假设你有一个接受 10 个参数的命令,并且 N 是 4,那么$4变成$1, $5变成$2等等。$10变成$7并且原来的$1, $2$3被丢弃。

如果 N 是零或者大于$#,位置参数不会改变(参数的总数,参见 第 7.2.1.2 节),并且命令不会产生任何效果。如果 N 没有给出,则默认为 1。返回状态为零,除非 N 大于$#或者小于零;否则为非零。

9.7.2. 示例

shift 语句通常在命令的参数数量事先未知时使用,例如,当用户可以根据需要给出任意数量的参数时。在这种情况下,参数通常在一个 while 循环中处理,测试条件为 (( $# ))。只要参数数量大于零,这个条件就为真。The$1变量和 shift 语句处理每个参数。每次执行 shift 时,参数的数量都会减少,并最终变为零,当参数数量变为零时,while 循环退出。

下面的示例,cleanup.sh,使用 shift 语句来处理 find 命令生成的列表中的每个文件

#!/bin/bash

# This script can clean up files that were last accessed over 365 days ago.

USAGE="Usage: $0 dir1 dir2 dir3 ... dirN"

if [ "$#" == "0" ]; then
	echo "$USAGE"
	exit 1
fi

while (( "$#" )); do

if [[ $(ls "$1") == "" ]]; then 
	echo "Empty directory, nothing to be done."
  else 
	find "$1" -type f -a -atime +365 -exec rm -i {} \;
fi

shift

done

Note-exec vs. xargs
 

上面的 find 命令可以用以下命令替换

findoptions| xargs [commands_to_execute_on_found_files]

xargs 命令从标准输入构建并执行命令行。这样做的好处是命令行会被填充,直到达到系统限制。只有当达到系统限制时,才会调用要执行的命令,在上面的示例中,这将是 rm。如果有更多参数,将会使用新的命令行,直到这个命令行被填满或者没有更多参数为止。使用 find -exec 做同样的事情,每次找到文件时都会调用要执行的命令来处理找到的文件。因此,使用 xargs 可以大大提高脚本的速度和你的计算机的性能。

在下一个示例中,我们修改了来自 第 8.2.4.4 节的脚本,以便它可以一次接受安装多个软件包

#!/bin/bash
if [ $# -lt 1 ]; then
        echo "Usage: $0 package(s)"
        exit 1
fi
while (($#)); do
	yum install "$1" << CONFIRM
y
CONFIRM
shift
done