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
Tellを使用します。find
我々は、現代的な形式の命令置換を使用し、$(...)
命令置換を引用して、分割+glob部分をスキップします(無言)。
以下を使用することもできます(まだGNUのみ)。
find . -type f -iname '*.db' \( -exec sqlite3 {} \; -o -true \) -quit
(終了状態は消えますがsqlite3
)
そしてzsh
:
setopt extendedglob # best in ~/.zshrc
sqlite3 ./**/*.(#i)db(D.[1])