13. 流程控制(三)
优质
小牛编辑
129浏览
2023-12-01
本节讲 for
的使用。语法:
for variable in words; do
commands
done
本质上,for
是将一个列表中的值依次赋值给一个指定的变量,执行命令,直到列表中的值使用完毕。示例:
#!/bin/bash
for i in word1 word2 word3; do
echo $i
done
for
的有趣之处在于构建列表的方式。所有扩展符都可以使用。以下是使用命令替换的示例:
#!/bin/bash
count=0
for i in $(cat ~/.bash_profile); do
count=$((count + 1))
echo "Word $count ($i) contains $(echo -n $i | wc -c) characters"
done
位置参数示例:
#!/bin/bash
for i in "$@"; do
echo $i
done
shell 变量 $@
包含命令行参数。另一个示例:
#!/bin/bash
for filename in "$@"; do
result=
if [ -f "$filename" ]; then
result="$filename is a regular file"
else
if [ -d "$filename" ]; then
result="$filename is a directory"
fi
fi
if [ -w "$filename" ]; then
result="$result and it is writable"
else
result="$result and it is not writable"
fi
echo "$result"
done
尝试运行该脚本,使用 *
等通配符来观察其结果。 以下是另一个示例脚本,该脚本对比两个目录,并列出在第一个目录而第二个目录中没有的文件。
#!/bin/bash
# cmp_dir - program to compare two directories
# Check for required arguments
if [ $# -ne 2 ]; then
echo "usage: $0 directory_1 directory_2" 1>&2
exit 1
fi
# Make sure both arguments are directories
if [ ! -d $1 ]; then
echo "$1 is not a directory!" 1>&2
exit 1
fi
if [ ! -d $2 ]; then
echo "$2 is not a directory!" 1>&2
exit 1
fi
# Process each file in directory_1, comparing it to directory_2
missing=0
for filename in $1/*; do
fn=$(basename "$filename")
if [ -f "$filename" ]; then
if [ ! -f "$2/$fn" ]; then
echo "$fn is missing from $2"
missing=$((missing + 1))
fi
fi
done
echo "$missing files missing"
现在来改善之前的打印系统信息的脚本:
home_space()
{
# Only the superuser can get this information
if [ "$(id -u)" = "0" ]; then
echo "<h2>Home directory space by user</h2>"
echo "<pre>"
echo "Bytes Directory"
du -s /home/* | sort -nr
echo "</pre>"
fi
} # end of home_space
一个新版本:
home_space()
{
echo "<h2>Home directory space by user</h2>"
echo "<pre>"
format="%8s%10s%10s %-s\n"
printf "$format" "Dirs" "Files" "Blocks" "Directory"
printf "$format" "----" "-----" "------" "---------"
if [ $(id -u) = "0" ]; then
dir_list="/home/*"
else
dir_list=$HOME
fi
for home_dir in $dir_list; do
total_dirs=$(find $home_dir -type d | wc -l)
total_files=$(find $home_dir -type f | wc -l)
total_blocks=$(du -s $home_dir)
printf "$format" $total_dirs $total_files $total_blocks
done
echo "</pre>"
} # end of home_space
该版本引入了一个新的命令 printf
。用于格式化输出字符串。格式字符串的格式可以参考:
同时引入了 find
命令,用于查找符合标准的文件或目录。 wc
命令,用于统计出现的文件和目录数量。 id
命令用于检查用户是否是超级用户。 在另一个函数中使用 for
:
system_info()
{
# Find any release files in /etc
if ls /etc/*release 1>/dev/null 2>&1; then
echo "<h2>System release info</h2>"
echo "<pre>"
for i in /etc/*release; do
# Since we can't be sure of the
# length of the file, only
# display the first line.
head -n 1 $i
done
uname -orp
echo "</pre>"
fi
} # end of system_info