mdfind, используемый для создания символических ссылок, не работает должным образом

Я пытаюсь использовать вывод mdfind для создания набора символических ссылок. Вывод mdfind выглядит следующим образом:

/pathtofile1/
/pathtofile2/
/pathtofile3/

Итак, я использовал sed, чтобы добавить ln -s в начало каждой строки, и awk {print $0 "/directory where I want this/"};

после того, как мой однострочный скрипт успешно выводит это:

ln -s "/pathtofile1/" "/каталог, где я хочу это"
ln -s "/pathtofile2/" "/каталог, где я хочу это"
ln -s "/pathtofile3/" "/каталог, где Я хочу этот"

Проблема в том, что когда я запускаю это, я получаю эту ошибку: «/ каталог, где я хочу это: файл не существует»

Странно то, что когда я запускаю эти строки по отдельности, они создают ссылки, как и ожидалось, но выполнение всей команды возвращает указанную выше ошибку.

Любые идеи?

Я не думаю, что это идеальный способ сделать то, что я пытаюсь сделать, поэтому дайте мне знать, если у вас есть лучшие решения.


Отредактировано с дополнительной информацией.

#! /bin/bash
itemList=`mdfind -s "$1"| awk '{ print "ln -s \""$0"\" \"/Users/username/Local/Recent\""}'`
echo "$itemList"
`$itemList`

$1 — это тестовый *.savedSearch, возвращающий список файлов.

Мой результат (из эха):

ln -s "/Users/username/Dropbox/Document.pdf" "/Users/username/Local/Recent"
ln -s "/Users/username/Dropbox/Document2.pdf" "/Users/username/Local/Recent"

и ошибка, которую я получаю:

ln: "/Users/username/Local/Recent": Нет такого файла или каталога

Но если я запускаю копирование и вставку каждой строки по отдельности, ссылки создаются, как и ожидалось.


person Andrew J. Freyer    schedule 18.12.2009    source источник
comment
изменил это, чтобы просто использовать «awk», и ошибка все еще происходит...   -  person Andrew J. Freyer    schedule 19.12.2009
comment
Помогло ли какое-нибудь из решений? (Считается хорошим этикетом SO либо пометить один ответ как принятый, либо лучше объяснить, что вы ищете.)   -  person Ned Deily    schedule 20.12.2009
comment
Одной из ваших проблем является последняя строка вашего скрипта, которая содержит $items в обратных кавычках. hat сводит список в одну строку, выполняет ее и фиксирует стандартный вывод (его нет), а затем выполняет эту пустую строку! Предложение: выведите точку с запятой в awk после второй кавычки, заключающей имя целевого каталога. Это оставит вас с действительной оболочкой. Затем, когда дело доходит до выполнения «скрипта», не заключайте его в обратные кавычки. Вам может понадобиться eval, или вы можете просто направить вывод сценария awk в sh (или bash), опционально с -x для трассировки.   -  person Jonathan Leffler    schedule 29.08.2012


Ответы (2)


Один из способов сделать это простым:

mdfind -0 "query" | ( cd "/Users/username/Local/Recent" ; xargs -0 -I path ln -s path . )

Это, конечно, не обрабатывает повторяющиеся имена файлов и т. д.

РЕДАКТИРОВАТЬ:

Причины, по которым ваше решение не работает, заключаются в том, что, во-первых, содержимое $itemList выполняется как одна длинная команда (т. е. переводы строк, выводимые awk, игнорируются), а затем, во-вторых, подстановка команд происходит перед удалением кавычек. То, что фактически обрабатывается, примерно эквивалентно:

ln '-s' '"/pathtofile1/"' '"/to"' 'ln' '-s' '"/pathtofile2/"' '"/to"' 'ln' '-s' '"/pathtofile3/"' '"/to"'

/bin/ln распознает это как:

ln [-Ffhinsv] source_file ... target_dir

форме команды и проверяет, является ли последний параметр существующим каталогом. Этот тест не пройден, потому что имя каталога включает окружающие кавычки. Обратите внимание на сообщение об ошибке, о котором вы сообщаете и сравниваете:

$ ln a b c "/Users/username/Local/Recent"
ln: /Users/username/Local/Recent: No such file or directory
$ ln a b c '"/Users/username/Local/Recent"'
ln: "/Users/username/Local/Recent": No such file or directory

Итак, мораль этой истории такова: когда вы имеете дело с именами файлов в оболочке, самое безопасное решение — избегать обработки имен файлов оболочкой, чтобы вам не приходилось иметь дело с кавычками и другими побочными эффектами (что является большой проблемой). преимущества решения xargs) и не усложняйте его: избегайте создания сложных многострочных команд оболочки. Слишком легко получить неожиданные результаты.

person Ned Deily    schedule 18.12.2009

Было бы гораздо проще определить, в чем проблема, если бы вы использовали некоторые реальные или, по крайней мере, правдоподобные пути в качестве примеров, но ln не собирается создавать для вас эти каталоги, если вы этого хотите.

person Azeem.Butt    schedule 18.12.2009
comment
Я не надеюсь создавать каталоги - на самом деле каталог существует, потому что, как я сказал выше, отдельные строки работают нормально. Например, если я добавлю | head -1, команда будет запущена. - person Andrew J. Freyer; 19.12.2009
comment
Так что опубликуйте свой фактический источник и фактический пример некоторого фактического ввода - person Azeem.Butt; 19.12.2009
comment
Почему бы вам не перебирать результаты по отдельности, а не упаковывать их все в одну большую строку? - person Azeem.Butt; 19.12.2009
comment
Я дурачился с этой возможностью, у меня были проблемы с вызовом ее построчно. Любая идея, почему это не работает? Это необычная стратегия? - person Andrew J. Freyer; 19.12.2009
comment
Я бы сказал, что бросать обратные кавычки вокруг многострочной строки и ожидать, что она сделает что-то полезное, довольно редко, но у кого-то может быть другое мнение. - person Azeem.Butt; 19.12.2009
comment
Я успешно использовал это в прошлом, особенно с уничтожением всего списка повторяющихся процессов. kill 123 kill 456 kill 234 Убивает все процессы... возможно, это особый случай. - person Andrew J. Freyer; 19.12.2009