为什么 "mpv $(ls video\ *)" 与 "mpv video\ *" 不同? (请帮助 noobie 使用 shell)

why "mpv $(ls video\ *)" is not the same as "mpv video\ *"? (pls help noobie to work with shell)

所以,问题是 - 我有一个文件列表,我想将它们发送到一个程序中,这样它就可以在同一个进程中处理这个列表。我的意思是,例如我有一堆视频文件,我想用 mpv 播放,但我需要将它们传递到我可以用 ls video\ * | sort -k2 创建的特定顺序。每个文件的名称类似于 video [number] - [title].mp4。我想按 [number] 列对它们进行排序,所以我调用了 lssort 程序,因为我的 shell (zsh) 不能自己做这样的事情(我想).

所以我输入了 ls video\ * | sort -k2,它给了我一个我想要的排序列表。但是当我试图用 mpv $(ls video\ * | sort -k2) 将它传递给 mpv 时,出于某种原因,mpv 不会逐行读取文件名,而是从 space 到 space 读取它们(我意思是,这不是 mpv 的问题,而是 shell 给 mpv 的参数由 spaces 分隔,但不是行)。

我尝试用引号将每一行括起来,尝试创建一个单行列表,同时尝试两者,但 none 如果可行的话。 Shell 总是用 space 分隔文件名 space,它会忽略换行符或引号。都是因为spaces,不是吗?

why “mpv $(ls video\ *)” is not the same as “mpv video\ *”?

因为command substitution undergoes word splitting while the result of filename expansion does not, because word splitting happens before filename expansion (see shell expansions).

的结果

分词是一件神奇的事情,当参数未被引用时,它会被使用 whitespaces 吐出参数。这意味着对于一个只打印参数计数的函数 f() { echo $#; } 具有 var="a b c variable with spaces"; f $var - 当 $var 未被引用时,函数 f 将接收 6 个参数 - [ 的结果=12=] 膨胀吐白spaces.

command substitution的结果不被引用时,它会进行分词。这意味着在 f $(echo a b c) 中函数 f 将接收 3 个参数。

因为你的文件中有一个 space video\ * - 当你传递命令 ls 的未引用结果时,输出字符串为白色 space 它将吐在白色spaces上。所以 video 和其余的将是单独的参数。

Do not parse lsls 用于 shell 中的漂亮打印 - 仅此而已。大多数情况很容易转换为 find -execfind | xargs 例如你想: find . -maxdepth 1 -type f -name 'video *' | sort -k2 | xargs -d '\n' mpv 或零终止流更好: find . -maxdepth 1 -type f -name 'video *' -print0 | sort -z -k2 | xargs -0 mpv.

It's all because spaces, isn't?

是的。