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