
Bashはこの方法で他のコマンドを標準入力に接続できます。
$ ls /bin/aud* | cat
/bin/audacity
/bin/audiocompose
/bin/audiosend
...
...そしてこの方法で:
$ cat <(ls /bin/aud*)
/bin/audacity
/bin/audiocompose
/bin/audiosend
...
ただし、同じパターンを使用してSQLiteにクエリを送信しようとすると、最初のフォームに次の結果が表示されます。
$ echo "select count(*) from urls;" | \
sqlite3 ~/.config/google-chrome/Default/History
5983
...しかし、2番目のエラーは次のとおりです。
$ sqlite3 ~/.config/google-chrome/Default/History \
<(echo "select count(*) from urls;")
Error: near "/": syntax error
これは驚くべきことです... SQLステートメントはシェルによって挿入または混乱しません。
$ echo "select count(*) from urls;"
echo "select count(*) from urls;"
これはどちらかとは関係ありませんecho
。確かにリダイレクトに使用できます。
$ cat <(echo Foo)
Foo
私が考えることができるのは、データベースファイルのパスが何らかの方法で誤って解釈され、SQL文に渡されたことです。 ( "/"を含む唯一の場所です。 "/近くの構文エラーの唯一の説明です。" 。
しかし、なぜ?どんなアイデアがありますか?
答え1
I / Oリダイレクトの2番目の形式(<(cmd)
)は、cmd | other-cmd
最初の形式()とは異なる動作をします。
1つ目はの出力cmd
をの入力に接続しますother-cmd
が、2つ目はパス/dev/fd
または名前付きパイプコマンドのパスです。の標準出力はそのパイプのもう一方の端にバインドされますが、これは標準入力またはファイルパスから読み取るコマンドと同じですcmd
。動作はそうではないので、2つの形式のI / Oリダイレクトの違いを明らかにします。cat
sqlite3
sqlite3
予想するデータベースパスの後にはオプションのSQL文があるため、この代替パスをSQLに解析しようとしましたが失敗します。
ちなみに、これはI / Oリダイレクトがまったく必要ないことを意味します。このコマンドは、試した形式よりも目的の操作を効率的に実行します。
$ sqlite3 ~/.config/google-chrome/Default/History "select count(*) from urls"
sqlite3
単一のSQL文をコマンドラインパラメータとして渡すときは、セミコロンで終わる文は必要ありません。
答え2
$ echo <(echo "hi")
/dev/fd/63
/dev/fd/63
SQLではないため、sqlite3
表示されたエラーメッセージで失敗します。cat
対照的に、ファイルの読み取り(または標準入力の読み取り)には非常に良いです。生成された名前付きパイプまたは/dev/fd
ファイル<(list)
は標準入力ではありません。