#!/usr/bin/bash
dirs="$(ls /)"
IFS=' ' read -a dir <<<"$dirs"
for item in "${dir[@]}"; do
if [[ $item != "proc" ]]; then
du -sh /$item
fi
done
我想在/中列出文件夹,并检查它们的大小,ls /
响应bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
,但是如果我更改为<,则结果只有一项0 /bin
。 / p>
#!/usr/bin/bash
dirs="bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var"
IFS=' ' read -a dir <<<"$dirs"
for item in "${dir[@]}"; do
if [[ $item != "proc" ]]; then
du -sh /$item
fi
done
结果将是正确的,如何使其起作用?
答案 0 :(得分:3)
在数个帖子中多次提到了这一点。不要以编程方式使用ls
的输出。它有很多陷阱。参见Why you shouldn't parse the output of ls(1)
您需要做的就是外壳程序本身提供的glob扩展,以列出/
目录下的目录。另外,您不应使用变量来存储多词内容。您需要使用数组!
shopt -s nullglob
topDirs=(/*/)
现在topDirs
数组将包含根目录下的所有文件夹名称,您可以使用循环来解析,
for dir in "${topDirs[@]}"; do
if [[ $dir != "/proc/" ]]; then
du -sh "$dir"
fi
done
至于为什么您的代码不起作用,执行ls /
并不是列出目录的有效glob扩展,它列出了两个文件和目录。 ls
的输出也是换行符。变量dirs
的内容由换行符分隔,因此您在IFS=' '
上进行拆分的逻辑从不起作用。它只会将第一行存储在返回的列表中。您应该使用mapfile
或readarray
来读入以换行符分隔的条目列表
mapfile -t dir <<<"$dirs"
但是整个逻辑存在疑问,因为ls
在包含空格或其他特殊字符的情况下会拆分文件名。因此最好避免这种情况,并如上所述进行全局扩展逻辑。
答案 1 :(得分:1)
不需要您的IFS
行。如果您确定没有目录包含空格(从IFS
行可以看出),可以使用:
dirs="$(ls /)"
for item in $dirs; do
if [[ $item != "proc" ]]; then
du -sh /$item
fi
done
请注意,您也可以省略[@]
,循环将在单词上重复(因此文件夹中的空格会中断此操作)。更好的是:
for item in /*/; do
if [[ $item != "proc" ]]; then
du -sh "$item"
fi
done
还将处理带有空格的目录。
答案 2 :(得分:1)
您正在做的事情简单得多:
find / -maxdepth 1 -type d -a ! -path / -a ! -path /proc | xargs du -sh
使用find
,您可以捕获同一级别的所有文件夹,但同时不包含/
和/proc
,最后您使用xargs
将文件夹列表传递给{{ 1}},以计算尺寸。
答案 3 :(得分:0)
尝试
mapfile -t dirs <<<"$(ls /)"
它必须给您结果而不用空格分开