Bash 将ls输出存储在变量中并拆分它不起作用
结果将是正确的,如何使其工作?如果不需要Bash 将ls输出存储在变量中并拆分它不起作用,bash,sh,Bash,Sh,结果将是正确的,如何使其工作?如果不需要行,则不需要行。如果您确定没有带空格的目录(从您的IFS行可以看出),您可以使用: #!/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 [[ $
行,则不需要行。如果您确定没有带空格的目录(从您的IFS
行可以看出),您可以使用:
#!/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
注意,您也可以省略[@]
,循环将在单词上迭代(因此文件夹中的空格将打破这一点)。更好的是:
dirs="$(ls /)"
for item in $dirs; do
if [[ $item != "proc" ]]; then
du -sh /$item
fi
done
还将处理带有空格的目录。不需要IFS
行。如果您确定没有带空格的目录(从您的IFS
行可以看出),您可以使用:
#!/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
注意,您也可以省略[@]
,循环将在单词上迭代(因此文件夹中的空格将打破这一点)。更好的是:
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
使用find
可以捕获该级别的所有文件夹,但同时不包括/
和/proc
,最后使用xargs
将文件夹列表传递给du
,以计算大小。您正在做的事情非常简单:
for item in /*/; do
if [[ $item != "proc" ]]; then
du -sh "$item"
fi
done
使用find
可以同时捕获该级别的所有文件夹,不包括/
和/proc
,最后使用xargs
将文件夹列表传递给du
,以计算大小。这已经在几篇文章中多次提到过。不要以编程方式使用ls
的输出。它有几个陷阱。看
您所需要的只是shell本身提供的glob扩展,以列出/
目录下的目录。此外,您不应该使用变量来存储多单词内容。你需要使用数组
find / -maxdepth 1 -type d -a ! -path / -a ! -path /proc | xargs du -sh
现在,topDirs
数组将包含根目录下的所有文件夹名称,您可以使用循环来解析这些名称
shopt -s nullglob
topDirs=(/*/)
至于代码不起作用的原因,执行ls/
不是列出目录的有效全局扩展,它同时列出了文件和目录。另外,ls
的输出是换行分隔的。变量dirs
的内容将用新行分隔,因此在IFS='
上拆分的逻辑将永远无法工作。它将只存储返回的列表中的第一行。您应该使用mapfile
或readarray
读取以换行符分隔的条目列表
for dir in "${topDirs[@]}"; do
if [[ $dir != "/proc/" ]]; then
du -sh "$dir"
fi
done
mapfile-tdir这已经在几篇文章中多次提到。不要以编程方式使用ls
的输出。它有几个陷阱。看
您所需要的只是shell本身提供的glob扩展,以列出/
目录下的目录。此外,您不应该使用变量来存储多单词内容。你需要使用数组
find / -maxdepth 1 -type d -a ! -path / -a ! -path /proc | xargs du -sh
现在,topDirs
数组将包含根目录下的所有文件夹名称,您可以使用循环来解析这些名称
shopt -s nullglob
topDirs=(/*/)
至于代码不起作用的原因,执行ls/
不是列出目录的有效全局扩展,它同时列出了文件和目录。另外,ls
的输出是换行分隔的。变量dirs
的内容将用新行分隔,因此在IFS='
上拆分的逻辑将永远无法工作。它将只存储返回的列表中的第一行。您应该使用mapfile
或readarray
读取以换行符分隔的条目列表
for dir in "${topDirs[@]}"; do
if [[ $dir != "/proc/" ]]; then
du -sh "$dir"
fi
done
mapfile-tdirtry
mapfile-tdirestry
mapfile-t dirs谢谢您提供的信息,但我正在学习shell脚本,请尝试练习顺便说一句,该命令不正确,因为它显示/文件夹的总大小,就像du-sh/???它显示的内容与脚本相同:du-sh/$item
。事实上,我的脚本(感谢xargs)相当于du-sh/bin/boot/dev/etc/home/lib/lib64/media/mnt/opt/root/run/sbin/srv/sys/tmp/usr/var
Oh!我懂了。。。你说对了一半。find的输出包括/
。让我编辑答案并更正它。我可以问一下-a是什么意思吗?如果我没有它,结果看起来是一样的谢谢这些信息,但是我正在学习shell脚本,试着练习一下。顺便说一下,这个命令不正确,因为它显示了/文件夹的总大小,就像du-sh/???它显示的内容与脚本相同:du-sh/$item
。事实上,我的脚本(感谢xargs)相当于du-sh/bin/boot/dev/etc/home/lib/lib64/media/mnt/opt/root/run/sbin/srv/sys/tmp/usr/var
Oh!我懂了。。。你说对了一半。find的输出包括/
。让我编辑答案并更正。我可以问-a是什么意思吗,结果看起来是一样的,如果我没有它就不会工作,就像执行du-sh/bin引导开发等home lib lib64 media mnt opt proc root运行sbin srv sys tmp usr var
它不会工作,就像执行du-sh/bin引导开发等home lib64 media mnt opt proc root运行sbin srv sys tmp usr var