Возможно, самым простым способом было бы скопировать двоичный файл ls
из какой-либо другой системы — например, по сети или на флэш-накопителе USB — и поместил в свой личный bin
каталог. Другой обходной путь — использовать stat
с подстановочными знаками.
$()
расширяется должным образом, но оболочка делает больше для результата, чем вы знаете. Кроме того, добавление буквенных кавычек к путевым именам почти никогда не бывает правильным (, если только вы не используете eval
где-то ).
Воспроизведение всех файлов MP3 в диапазоне ~/Documents/music
или ниже с помощьюvlc
:
find ~/Documents/music -type f -name '*.mp3' -exec vlc {} +
Это запустит vlc
как можно больше файлов MP3 одновременно.
Чтобы пропустить использование find
всех -вместе:
shopt -s globstar
vlc ~/Documents/music/**/*.mp3
Это будет работать до тех пор, пока у вас не будет большого количества файлов MP3 (, и в этом случае вы получите сообщение об ошибке, поскольку список аргументов станет слишком длинным ).
Универсальный объект **
"рекурсивно" соответствует файловой иерархии, но должен быть включен с помощью shopt -s globstar
вbash
(оболочке zsh
этот глобус включен по умолчанию ).
Ваша команда
vlc $(echo $(find ~/Documents/music -name "*.mp3" -exec echo "\"{}\" \n " \;) | head -n 1)
сначала выполнит find
,head
и echo
. Этот конвейер будет выводить
"/home/XXX/Documents/music/My Folder/1 - track/the name of track.mp3"
Затем оболочка разбивает эту строку на слова "/home/XXX/Documents/music/My
, Folder/1
, -
, track/the
, name
, of
и track.mp3"
по пробелам в строке.
vlc
будет вызываться с этими отдельными аргументами. В частности, аргумент -
может быть ошибочно принят за параметр, в то время как другие, скорее всего, будут восприниматься как отдельные операнды имени пути.
Это подробно объясняется в
Котировки не обрабатываются при выводе расширений. Если вы сделаете $(echo '"foo bar"')
или $(echo "\"foo bar\"")
, аргументом основной команды станет "foo
и bar"
. С буквальными кавычками и как два отдельных аргумента из-за разделения слов .
По умолчанию разбиение слов происходит на любых пробелах, пробелах или новых строках, поэтому из вывода find
вы не можете отличить, какие пробелы являются частью имени файла, а какие частью того, что find
печатает. чтобы разделить их. Даже в общем случае их нельзя отличить друг от друга, так как имена файлов также могут содержать символы новой строки...
Что вы можете сделать, так это:
find... -print0 | xargs -0 vlc
или
find... -exec vlc {} +
Первый выводит find
имена файлов, разделенные нулевыми байтами, и указывает xargs
ожидать именно этого. Однако не все системы имеют find -print0
и xargs -0
.
Второй имеет find
запуск самого себя vlc
, завершающий {} +
сообщает ему передать несколько имен файлов для одного вызова vlc
.
Если нужно найти очень большое количество файлов, и они не помещаются в одну командную строку, то оба они могут запустить vlc
более одного раза.
См.:
Использование echo
для отладки этого на самом деле не работает, так как он будет объединять свои аргументы с одним пробелом, делая невозможным определение разницы между echo foo bar
и echo "foo bar"
.