O redirecionamento de Bash não funciona para o comando SQLite

1

Bash permite que o encadeamento permaneça de outro comando dessa maneira ...

$ ls /bin/aud* | cat
/bin/audacity
/bin/audiocompose
/bin/audiosend
...

... e assim também:

$ cat <(ls /bin/aud*)
/bin/audacity
/bin/audiocompose
/bin/audiosend
...

No entanto, quando tentei os mesmos padrões para enviar uma consulta ao SQLite, recebi este da primeira forma ...

$ echo "select count(*) from urls;" | \
    sqlite3 ~/.config/google-chrome/Default/History
5983

... mas esse erro no segundo:

$ sqlite3 ~/.config/google-chrome/Default/History \
   <(echo "select count(*) from urls;")
Error: near "/": syntax error

Isso foi surpreendente ... A instrução SQL não é interpolada ou confundida pelo shell:

$ echo "select count(*) from urls;"
echo "select count(*) from urls;"

E também não é sobre o echo - definitivamente pode ser usado no redirecionamento:

$ cat <(echo Foo)
Foo

Tudo o que posso pensar é que, de alguma forma, o caminho para o arquivo de banco de dados é mal interpretado e transmitido como também a instrução SQL ... (esse é o único lugar que contém um '/' - a única explicação para um 'erro de sintaxe) perto de /').

Por que, no entanto? Alguma idéia?

    
por ttsiodras 07.06.2016 / 23:56

2 respostas

4

A segunda forma de redirecionamento de E / S ( <(cmd) ) simplesmente não se comporta da mesma maneira que o primeiro formulário ( cmd | other-cmd ).

O primeiro conecta a saída de cmd à entrada de other-cmd , mas o segundo substitui um caminho /dev/fd ou um pipe nomeado caminho para o comando. A saída padrão de cmd está vinculada à outra extremidade desse canal, mas isso só parece equivalente com comandos como cat , que lerá de stdin ou de um caminho de arquivo. sqlite3 não se comporta dessa maneira, portanto, expõe a diferença entre as duas formas de redirecionamento de E / S.

sqlite3 espera instruções SQL opcionais depois do caminho do BD, então ele tenta analisar esse caminho substituído como SQL e falha.

Aliás, isso significa que você não precisa do redirecionamento de E / S. Este comando faz o que você está querendo de forma mais eficiente do que qualquer forma que você tentou:

$ sqlite3 ~/.config/google-chrome/Default/History "select count(*) from urls"

Note que você não precisa do ponto-e-vírgula terminador de instrução ao passar uma única instrução SQL para sqlite3 como um parâmetro de linha de comando.

    
por 08.06.2016 / 00:50
1
$ echo <(echo "hi")
/dev/fd/63

/dev/fd/63 não é SQL, portanto sqlite3 falha com a mensagem de erro indicada. cat pelo contraste é muito bom em ler arquivos (ou também a partir de entrada padrão). O pipe nomeado ou o arquivo /dev/fd da construção <(list) criada não é a entrada padrão.

    
por 08.06.2016 / 00:44