遍历目录的内容
兼容的答案(不仅是 bash)
由于这个问题被标记为shell,因此有一种POSIX 兼容 方式:
#!/bin/sh
for file in "$1"/* ;do
[ -f "$file" ] && echo "Process '$file'."
done
就足够了(使用包含空格的文件名):
$ myscript.sh /path/to/dir
Process '/path/to/dir/foo'.
Process '/path/to/dir/bar'.
Process '/path/to/dir/foo bar'.
使用 any posix shell 可以很好地工作。使用bash、ksh、dash、zsh 和 busybox sh 测试。
#!/bin/sh
cd "$1" || exit 1
for file in * ;do
[ -f "$file" ] && echo "Process '$file'."
done
此版本不会打印路径:
$ myscript.sh /path/to/dir
Process 'foo'.
Process 'bar'.
Process 'foo bar'.
简介
我不喜欢在不需要时使用shopt...(此更改标准
bash 行为并降低脚本的可读性)。
使用标准 bash 有一种优雅的方法可以做到这一点,不需要 shopt。
当然,以前的答案在bash 下工作正常,但是。有一些
让你的脚本更强大、更灵活、更漂亮、更详细……
样本
#!/bin/bash
die() { echo >&2 "$0 ERROR: $@";exit 1;} # Emergency exit function
[ "$1" ] || die "Argument missing." # Exit unless argument submitted
[ -d "$1" ] || die "Arg '$1' is not a directory." # Exit if argument is not dir
cd "$1" || die "Can't access '$1'." # Exit unless access dir.
files=(*) # All files names in array $files
[ -f "$files" ] || die "No files found." # Exit if no files found
for file in "${files[@]}";do # foreach file:
echo Process "$file" # Process file
done
说明:考虑 globbing 与 真实文件
做的时候:
files=(/path/to/dir/*)
变量$files变成了一个数组,其中包含/path/to/dir/下的所有文件:
declare -p files
declare -a files=([0]="/path/to/dir/bar" [1]="/path/to/dir/baz" [2]="/path/to/dir/foo")
但是如果没有匹配 glob 模式,star 将不会被替换,数组变为:
declare -p files
declare -a files=([0]="/path/to/dir/*")
从那里。寻找$files 就像寻找${files[0]} 即:数组中的第一个字段。所以
[ -f "$files" ] || die "No files found."
将执行die 函数,除非数组files 的第一个字段 是文件([ -e "$files" ] 检查现有条目 ,[ -d "$files" ] 检查现有的目录,等等...参见man bash 或help test)。
但是你可以用一些基于字符串的测试替换这个文件系统测试,比如:
[ "$files" = "/path/to/dir/*" ] && die "No files found."
或者,使用数组长度:
((${#files[@]}==1)) && [ "${files##*/}" = "*" ] && die "No files found."