Bash

為什麼 $() 不能正確展開?

  • August 25, 2019

我想使用 vlc 播放目錄中的所有 .mp3 文件,所以我執行以下操作:

vlc $(find ~/Documents/music -name "*.mp3" -exec "echo \"{}\"" \;)

問題是我得到“vlc:未知選項或缺少強制參數’-D’”。估計是解析問題。

所以讓我們逐個文件來做:

echo $(echo $(find ~/Documents/music -name "*.mp3" -exec echo "\"{}\" \n " \;) | head -n 1)

我得到:

"/home/XXX/Documents/music/My Folder/1 - track/the name of track.mp3"

當我執行時:

vlc "/home/XXX/Documents/music/My Folder/1 - track/the name of track.mp3"

有用。

但是當我跑步時

vlc $(echo $(find ~/Documents/music -name "*.mp3" -exec echo "\"{}\" \n " \;) | head -n 1)

我得到:

cannot open file /home/XXX/the (No such file or directory)

如果沒有正確引用 vlc 的參數,這將是有意義的。但他們是?那麼為什麼它被作為一個不帶引號的字元串傳遞給 vlc 呢?

引號不會在擴展的輸出中處理。如果你這樣做了$(echo '"foo bar"'),或者$(echo "\"foo bar\""),最後作為主命令的參數的是"fooand bar"。使用文字引號,並且由於分而作為兩個不同的參數。

預設情況下,分詞發生在任何空格、空格或換行符上,因此從 的輸出中find,您無法區分哪個空格是文件名的一部分,以及哪個空格是find分隔它們的列印內容的一部分。即使在一般情況下,您也無法區分它們,因為文件名也可以包含換行符……

你可以做的是:

find ... -print0 | xargs -0 vlc 

或者

find ... -exec vlc {} +

第一個find輸出了用 NUL 字節分隔的文件名,並告訴xargs我們期待這一點。不過,並非所有系統都有find -print0and xargs -0

第二個find自己啟動vlc,尾隨{} +告訴它將多個文件名傳遞給vlc.

如果您要找到大量文件,並且它們不適合一個命令行,那麼這兩個文件可能會vlc多次啟動。

看:

使用echo它來調試它並沒有真正起作用,因為它將用一個空格連接它的參數,從而無法區分echo foo bar, 和echo "foo bar".

引用自:https://unix.stackexchange.com/questions/537282