Eu quero executar um comando a partir de um script bash que possui aspas simples e alguns outros comandos dentro de aspas simples e uma variável.
por exemplo repo forall -c '....$variable'
Nesse formato, $
é escapado e a variável não é expandida.
Tentei as seguintes variações, mas elas foram rejeitadas:
repo forall -c '...."$variable" '
repo forall -c " '....$variable' "
" repo forall -c '....$variable' "
repo forall -c "'" ....$variable "'"
Se eu substituir o valor no lugar da variável, o comando será executado perfeitamente.
Por favor, diga-me onde estou errado.
repo forall -c ' ...before... '"$variable"' ...after...'
bash
come aspas simples. Você não está dentrobash
ou as aspas simples não fazem parte dorepo
comando.Respostas:
Dentro de aspas simples, tudo é preservado literalmente, sem exceção.
Isso significa que você precisa fechar as aspas, inserir algo e depois inserir novamente.
A concatenação de palavras é simplesmente feita por justaposição. Como você pode verificar, cada uma das linhas acima é uma única palavra para o shell. As aspas (aspas simples ou duplas, dependendo da situação) não isolam as palavras. Eles são usados apenas para desativar a interpretação de vários caracteres especiais, como espaço em branco
$
,;
... Para um bom tutorial sobre como citar, consulte a resposta de Mark Reed. Também relevante: Quais caracteres precisam ser escapados no bash?Não concatenar cadeias interpretadas por um shell
Você deve absolutamente evitar a construção de comandos shell concatenando variáveis. Essa é uma má ideia semelhante à concatenação de fragmentos SQL (injeção de SQL!).
Geralmente, é possível ter espaços reservados no comando e fornecê-lo juntamente com variáveis para que o receptor possa recebê-las da lista de argumentos de chamada.
Por exemplo, o seguinte é muito inseguro. NÃO FAÇA ISTO
Se o conteúdo de
$myvar
não for confiável, aqui está uma exploração:Em vez da invocação acima, use argumentos posicionais. A seguinte invocação é melhor - não é explorável:
Observe o uso de marcações simples na atribuição de
script
, o que significa que é literalmente usado, sem expansão variável ou qualquer outra forma de interpretação.fonte
"some"thing' like'this
é tudo uma palavra para o shell. As aspas não terminam nada no que diz respeito à análise, e não há como um comando chamado pelo shell dizer o que foi citado como.O
repo
comando não pode se importar com o tipo de cotação que recebe. Se você precisar de expansão de parâmetro, use aspas duplas. Se isso significa que você acaba tendo que inverter uma série de coisas, use aspas simples para a maioria delas e, em seguida, separe-as e entre em duplas na parte em que você precisa que a expansão ocorra.A explicação segue, se você estiver interessado.
Quando você executa um comando a partir do shell, o que esse comando recebe como argumentos é uma matriz de cadeias terminadas em nulo. Essas cadeias podem conter absolutamente qualquer caractere não nulo.
Mas quando o shell está construindo esse conjunto de strings a partir de uma linha de comando, ele interpreta alguns caracteres especialmente; isso foi projetado para facilitar a digitação de comandos (na verdade, possível). Por exemplo, os espaços normalmente indicam o limite entre as strings na matriz; por esse motivo, os argumentos individuais às vezes são chamados de "palavras". Mas um argumento pode, no entanto, ter espaços; você só precisa de uma maneira de dizer ao shell que é isso que você deseja.
Você pode usar uma barra invertida na frente de qualquer caractere (incluindo espaço ou outra barra invertida) para dizer ao shell para tratar esse caractere literalmente. Mas enquanto você pode fazer algo assim:
echo \"Thank\ you.\ \ That\'ll\ be\ \$4.96,\ please,\"\ said\ the\ cashier
... pode ficar cansativo. Portanto, o shell oferece uma alternativa: aspas. Estes vêm em duas variedades principais.
Aspas duplas são chamadas de "aspas de agrupamento". Eles impedem que caracteres curinga e aliases sejam expandidos, mas principalmente são para incluir espaços em uma palavra. Outras coisas como expansão de parâmetro e comando (o tipo de coisa sinalizada por a
$
) ainda acontecem. E, claro, se você deseja uma aspas duplas literal dentro de aspas duplas, é necessário fazer uma barra invertida:echo "\"Thank you. That'll be \$4.96, please,\" said the cashier"
Aspas simples são mais draconianas. Tudo entre eles é tomado completamente literalmente, incluindo barras invertidas. Não há absolutamente nenhuma maneira de obter uma citação única literal dentro de aspas simples.
Felizmente, as aspas no shell não são delimitadores de palavras ; sozinhos, eles não terminam uma palavra. Você pode entrar e sair de aspas, inclusive entre diferentes tipos de aspas, dentro da mesma palavra para obter o resultado desejado:
echo '"Thank you. That'\''ll be $4.96, please," said the cashier'
Portanto, isso é mais fácil - muito menos barras invertidas, embora a seqüência de aspas simples, de barra invertida e de aspas simples literal e de aspas simples demore um tempo para se acostumar.
Os shells modernos adicionaram outro estilo de citação não especificado pelo padrão POSIX, no qual as aspas simples à esquerda são prefixadas com um cifrão. As strings assim citadas seguem convenções semelhantes às literais de strings na linguagem de programação ANSI C e, portanto, às vezes são chamadas de "strings ANSI" e o par
$'
...'
"aspas ANSI". Dentro de tais cadeias, o conselho acima sobre barras invertidas sendo literalmente não se aplica mais. Em vez disso, eles se tornam especiais novamente - não apenas você pode incluir aspas ou barra invertida literal colocando uma barra invertida antes, mas o shell também expande as fugas de caracteres ANSI C (como\n
para uma nova linha,\t
para tab e\xHH
para o caractere com código hexadecimalHH
) Caso contrário, no entanto, eles se comportam como cadeias de caracteres simples: nenhuma substituição de parâmetro ou comando ocorre:O importante a ser observado é que a única sequência recebida como argumento para o
echo
comando é exatamente a mesma em todos esses exemplos. Após o shell concluir a análise de uma linha de comando, não há como executar o comando para saber como foi citado. Mesmo que quisesse.fonte
$'string'
formato é compatível com POSIX? Além disso, existe um nome para isso?$'string'
é uma extensão não-POSIX, que eu já vi referida como "seqüências de caracteres ANSI"; Eu incorporei esses fatos na resposta. Tais strings funcionam na maioria dos shells modernos compatíveis com Bourne: bash, dash, ksh (AT&T e PD) e zsh todos os suportam.Abaixo está o que funcionou para mim -
fonte
QUOTE
em uma variável separada é completamente supérfluo; aspas simples dentro de aspas duplas são apenas um caractere comum. (Além disso, não use letras maiúsculas para as suas variáveis privadas.)EDIT: (Conforme os comentários em questão :)
Eu estive investigando isso desde então. Eu tive a sorte de ter repo deitado. Ainda não está claro para mim se você precisa colocar seus comandos entre aspas simples à força. Examinei a sintaxe do repositório e não acho que você precise. Você pode usar aspas duplas ao redor do seu comando e, em seguida, usar as aspas simples e duplas que precisar dentro, desde que você escape das aspas duplas.
fonte
basta usar printf
ao invés de
use printf para substituir o token de variável pela variável expandida.
Por exemplo:
fonte
printf
realmente não compra nada aqui, e deixar de citar o comando subsititution causa novos problemas de cotação.Variáveis podem conter aspas simples.
fonte
"$myvar"
aspas duplas.Isso funciona para você?
fonte