Bash语法奇怪,文件带有空格

Bash语法奇怪,文件带有空格,bash,shell,unix,Bash,Shell,Unix,这里有一个你可能很熟悉的问题:我想查询一下我在Mac上的磁盘使用情况,所以我在我的主目录中进行了尝试 ~/$> for file in `ls`; do du -hs $file; done 有输出 55M Applications 107M Desktop 132G Documents 5.1G Downloads 16G Library 457M Music 53M Pictures du: VirtualBox: No such fi

这里有一个你可能很熟悉的问题:我想查询一下我在Mac上的磁盘使用情况,所以我在我的主目录中进行了尝试

~/$> for file in `ls`; do du -hs $file; done
有输出

 55M    Applications
107M    Desktop
132G    Documents
5.1G    Downloads
 16G    Library
457M    Music
 53M    Pictures
du: VirtualBox: No such file or directory
du: VMs: No such file or directory
这很好,除了最后一个,因为它是一个名为“VirtualBox VMs”的目录——名称中有一个空格。我用谷歌搜索它(实际上,我所要做的就是开始键入“bash loop…”,然后它自动完成为“bash loop over files with spaces”--谢谢谷歌!),我得到了这个问题,这是第一个结果

如果你仔细阅读这篇文章,你会发现很多复杂的解决方案使用了
xargs
或者一些奇怪的东西。当然,我可以编写自己的函数来处理这些情况,但我非常坚持使用单线解决方案。因此,在我看来,最好的解决方案(尽管不是最高投票或接受的解决方案)是

有些反常的是,以下方法不起作用:

  • 删除引号

    for file in *; do du -hs ${file}; done  #splits on spaces and throws error
    
  • 使用
    ls
    ,即使使用引号:

    for file in `ls`; do du -hs "${file}"; done #splits on spaces and throws error
    

  • 我的问题是,某位bash专家能否向我解释所有这些之间的区别,以及失败的原因?

    意识到工作案例扩展到:
    du-hs“VirtualBox VM”

  • 对于这种情况,问题在于命令扩展为:
    du-hs VirtualBox虚拟机

    这会将两个文件名传递给
    du
    命令

  • 对于这种情况,问题在于
    For
    命令会看到两个单独的标记。因此,迭代将分别迭代每一次。
    du-hs-VirtualBox

    du-hs-VMs


  • 这一切都可以通过以下事实来解释:分词发生在进程替换和参数扩展之后。因此,
    $(ls)
    以及
    ${file}
    的结果会进行分词,而
    “${file}”中的双引号
    禁止分词。

    将是一个开始。您也可以阅读…并且阅读关于错误代码的错误原因的解释是另一个有用的地方。谢谢伙计们,这是我需要的东西Yo shellcheck是一个很好的工具,也是一个很好的资源
    for file in `ls`; do du -hs "${file}"; done #splits on spaces and throws error