我正在尝试查找一个文件,find
然后将找到的路径传递给sqlite3
.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 %;'
为什么后面的命令根本不执行任何操作?
答案1
在:
... | xargs cmd
根据实现,cmd
的 stdin 是/dev/null
或 那个管道。它不可能是外部标准输入,因为它会因管道而丢失。
$ 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
(可能是您正在使用的GNU -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])