O echo
comando não está incluindo o texto completo que eu forneço. Por exemplo, se eu fizer:
$ echo ' echo PARAM=` grep $ARG /var/tmp/setfile | awk '{print $2}' ` '
Emite:
echo PARAM=` grep $ARG /var/tmp/setfile | awk {print } `
As aspas simples ( '
) que eu tinha no meu comando echo não estão incluídas. Se eu mudar para aspas duplas:
$ echo " echo PARAM=` grep $ARG /var/tmp/setfile | awk '{print $2}' ` "
echo
não produz nada! Por que está deixando de fora as aspas simples no primeiro exemplo e não produzindo nada no segundo? Como faço para que ele produza exatamente o que digitei?
Respostas:
Seu shell está interpretando as aspas, ambas
'
e"
antes mesmo que elas cheguemecho
. Geralmente, coloco aspas duplas em volta do meu argumento para ecoar, mesmo que desnecessárias; por exemplo:Portanto, no seu primeiro exemplo, se você deseja incluir aspas literais em sua saída, elas precisam ser escapadas:
Ou eles já devem ser usados dentro de um argumento citado (mas não pode ser o mesmo tipo de citação, ou você precisará escapar de qualquer maneira):
No seu segundo exemplo, você está executando uma substituição de comando no meio da string:
As coisas que começam com
$
também são tratadas especialmente pelo shell - as tratam como variáveis e as substituem por seus valores. Como provavelmente nenhuma dessas variáveis está definida no seu shell, na verdade, apenas executaComo
grep
apenas vê um argumento, ele assume que o argumento é o padrão que você está procurando e que o local em que ele deve ler os dados é stdin, impedindo a entrada de informações. É por isso que seu segundo comando parece travar.Isso não acontecerá se você citar o argumento (e é por isso que seu primeiro exemplo quase funcionou), portanto, essa é uma maneira de obter a saída desejada:
Você também pode citá-lo duas vezes, mas precisará escapar de
$
s para que o shell não os resolva como variáveis e os backticks para que o shell não execute a substituição de comando imediatamente:fonte
Não vou entrar em muitos detalhes sobre por que suas tentativas se comportam dessa maneira, porque a resposta de Michael Mrozek cobre isso muito bem. Em poucas palavras, tudo entre aspas simples (
'…'
) é interpretado literalmente (e, em particular, a primeira'
marca o final da cadeia literal), enquanto mantém`
e$
seu significado especial entre"…"
.Não há aspas dentro de aspas simples, portanto, você não pode colocar uma aspas única em uma sequência de aspas simples. Existe, no entanto, um idioma que se parece com ele:
Isso é impresso
foo'bar
, porque o argumento toecho
é feito da cadeia de três caracteres entre aspas simplesfoo
, concatenada com o caractere único'
(obtido ao proteger o caractere'
de seu significado especial através do anterior\
), concatenada com a cadeia de três caracteres entre aspas simplesbar
. Portanto, embora não seja exatamente o que acontece nos bastidores, você pode pensar'\''
em uma maneira de incluir uma única citação dentro de uma sequência de aspas simples.Se você deseja imprimir seqüências complexas de várias linhas, uma ferramenta melhor é o documento aqui . Um documento aqui consiste nos dois caracteres
<<
seguidos por um marcador como<<EOF
, em seguida, algumas linhas de texto, depois o marcador final sozinho em sua linha. Se o marcador for citado de alguma forma ('EOF'
ou"EOF"
ou\EOF
'E "" OF "ou ...), o texto será interpretado literalmente (como dentro de aspas simples, exceto que mesmo'
é um caractere comum). Se o marcador não estiver entre aspas, o texto será interpretado como em uma sequência de aspas duplas,$\`
mantendo seu status especial (mas as"
novas linhas serão interpretadas literalmente).fonte
Ok, isso vai funcionar: -
Testando aqui: -
fonte
A sugestão de Gilles de usar um documento aqui é muito boa e até funciona em linguagens de script como Perl. Como exemplo específico, com base em sua resposta à questão do OP,
É verdade que este exemplo é um pouco artificial, mas achei uma técnica útil para, por exemplo, enviar instruções SQL para
psql
(em vez decat
).(Observe que qualquer caractere não espacial não alfanumérico pode ser usado no lugar da
#
construção de aspas genérica acima, mas o hash parecia se destacar bem neste exemplo e não é tratado como um comentário.)fonte
Vamos assumir o seu comando
e primeiro divida-o em palavras, usando espaço em branco não citado como delimitador:
Em seguida, fazemos a expansão dos parâmetros: expanda,
$…
mas não dentro'…'
. Como$2
está vazio (a menos que você o defina por exemploset -- …
), ele será substituído por uma string vazia.Em seguida, faça a remoção da cotação.
Esses argumentos são passados para eco, que os imprimirá um após o outro, separados por um único espaço.
Espero que esta instrução passo a passo torne o comportamento observado mais claro. Para evitar o problema, escape aspas simples como esta:
Isso encerrará a sequência de aspas simples, adicionará uma aspas simples (com escape) à palavra e iniciará uma nova sequência de aspas simples, tudo sem desmembrar a palavra.
fonte