Por exemplo:
me$ FOO="BAR * BAR"
me$ echo $FOO
BAR file1 file2 file3 file4 BAR
e usando o \
caractere de escape:
me$ FOO="BAR \* BAR"
me$ echo $FOO
BAR \* BAR
Obviamente estou fazendo algo estúpido.
Como obtenho a saída BAR * BAR
?
Citar quando a configuração $FOO
não é suficiente. Você também precisa citar a referência da variável:
me$ FOO="BAR * BAR"
me$ echo "$FOO"
BAR * BAR
RESPOSTA CURTA
Como outros já disseram - você deve sempre citar as variáveis para evitar comportamentos estranhos. Portanto, use echo "$ foo" em vez de apenas echo $ foo .
RESPOSTA LONGA
Eu acho que esse exemplo merece mais explicações, porque há mais coisas acontecendo do que parece.
Eu posso ver onde está sua confusão, porque depois de executar seu primeiro exemplo, você provavelmente pensou que o shell está obviamente fazendo:
Então, do seu primeiro exemplo:
Após a expansão do parâmetro é equivalente a:
E após a expansão do nome do arquivo é equivalente a:
E se você apenas digitar
echo BAR * BAR
na linha de comando, verá que eles são equivalentes.Então você provavelmente pensou: "se eu escapar do *, posso impedir a expansão do nome do arquivo"
Então, do seu segundo exemplo:
Após a expansão do parâmetro deve ser equivalente a:
E após a expansão do nome do arquivo deve ser equivalente a:
E se você tentar digitar "echo BAR \ * BAR" diretamente na linha de comando, ele realmente imprimirá "BAR * BAR" porque a expansão do nome do arquivo é impedida pela fuga.
Então, por que usar $ foo não funcionou?
É porque existe uma terceira expansão - Remoção de cotação. A partir do bash, a remoção manual de cotações é:
Então, o que acontece é que, quando você digita o comando diretamente na linha de comando, o caractere de escape não é o resultado de uma expansão anterior, portanto o BASH o remove antes de enviá-lo ao comando echo, mas no segundo exemplo, o "\ *" era o resultado de uma expansão anterior do parâmetro, portanto NÃO é removida. Como resultado, o eco recebe "\ *" e é isso que imprime.
Observe que a diferença entre o primeiro exemplo - "*" não está incluída nos caracteres que serão removidos pela Remoção de cotação.
Espero que isto faça sentido. No final, a conclusão do mesmo - basta usar aspas. Eu apenas pensei em explicar por que escapar, que logicamente deveria funcionar se apenas a expansão Parameter e Filename estiver em jogo, não funcionou.
Para uma explicação completa das expansões do BASH, consulte:
http://www.gnu.org/software/bash/manual/bashref.html#Shell-Expansions
fonte
Vou adicionar um pouco a esse tópico antigo.
Normalmente você usaria
No entanto, tive problemas mesmo com essa sintaxe. Considere o seguinte script.
As
*
necessidades devem ser transmitidas literalmente paracurl
, mas os mesmos problemas surgirão. O exemplo acima não funcionará (ele será expandido para nomes de arquivos no diretório atual) e nem funcionará\*
. Você também não pode citar$curl_opts
porque será reconhecido como uma opção única (inválida) paracurl
.Portanto, eu recomendaria o uso da
bash
variável$GLOBIGNORE
para impedir a expansão do nome do arquivo completamente, se aplicado ao padrão global, ou usar oset -f
sinalizador interno.Aplicando ao seu exemplo original:
fonte
SELECT * FROM etc.
: essa é a única maneira que funciona.fonte
fonte
Pode valer a pena adquirir o hábito de usar,
printf
e nãoecho
na linha de comando.Neste exemplo, não oferece muitos benefícios, mas pode ser mais útil com saídas mais complexas.
fonte