cmd2 `cmd1` vs cmd1 | xargs cmd2

Я пытаюсь найти файл с find а затем передать найденный путь к sqlite3 . Я просто sqlite> подсказку sqlite> если моя команда имеет форму:

 sqlite3 `find . -type f -iname "*.db" | head -n1` 

Но эти формы не работают:

 find . -type f -iname "*.db" | head -n1 | xargs sqlite3 find . -type f -iname "*.db" | head -n1 | xargs -I% sh -c 'sqlite3 %;' 

Почему последние команды просто ничего не делают?

В:

 ... | xargs cmd 

в зависимости от реализации, stdin cmd – либо /dev/null либо этот канал. Это не может быть внешним stdin, поскольку это потеряно из-за трубопровода.

 $ echo /proc/self/fd/0 | gnu-xargs ls -ld lr-x------ 1 me me 64 Dec 11 22:04 /proc/self/fd/0 -> /dev/null $ echo /proc/self/fd/0 | busybox-or-solaris-...-xargs ls -ld lr-x------ 1 me me 64 Dec 11 22:04 /proc/self/fd/0 -> pipe:[99839] 

В любом случае sqlite3 не сможет читать какие-либо данные от вас.

:

 sqlite3 `find . -type f -iname "*.db" | head -n1` 

команда берет первую строку первого пути к файлу, возвращаемого find , разбивает его по $IFS , выполняет подтачивание на них и передает полученные слова в виде различных аргументов sqlite3. Это мало смысла.

С GNU find (возможно, что вы используете с тех пор, как вы используете -iname ):

 sqlite3 "$(find . -type f -iname "*.db" -print -quit)" 

Мы используем -exit чтобы сказать find для выхода после печати первого найденного файла. Мы используем современную форму подстановки команд $(...) и пропускаем часть split + glob (что не имеет смысла), цитируя подстановку команд.

Вы также можете использовать (по-прежнему GNU):

 find . -type f -iname '*.db' \( -exec sqlite3 {} \; -o -true \) -quit 

(хотя вы потеряете статус выхода sqlite3 ).

С zsh :

 setopt extendedglob # best in ~/.zshrc sqlite3 ./**/*.(#i)db(D.[1])