Pergunta Geral:
No Bash, eu sei que o uso da variável myvar
pode ser feito de duas maneiras:
# Define a variable:
bash$ myvar="two words"
# Method one to dereference:
bash$ echo $myvar
two words
# Method two to dereference:
bash$ echo "$myvar"
two words
No caso acima, o comportamento é idêntico. Isso é por causa de como echo
funciona. Em outros utilitários Unix, se as palavras estão agrupadas com aspas duplas fará uma enorme diferença:
bash$ myfile="Cool Song.mp3"
bash$ rm "$myfile" # Deletes "Cool Song.mp3".
bash$ rm $myfile # Tries to delete "Cool" and "Song.mp3".
Gostaria de saber qual é o significado mais profundo dessa diferença. Mais importante, como posso visualizar exatamente o que será passado para o comando, para que eu possa ver se foi citado corretamente?
Exemplo ímpar específico:
Vou apenas escrever o código com o comportamento observado:
bash$ mydate="--date=format:\"%Y-%m-%d T%H\""
bash$ git log "$mydate" # This works great.
bash$ git log $mydate
fatal: ambiguous argument 'T%H"': unknown revision or path not in the working tree.
Por que preciso de aspas duplas? O que exatamente o git-log está vendo depois que a variável é desreferenciada sem aspas duplas?
Mas agora veja isso:
bash$ nospace="--date=format:\"%Y-%m-%d\""
bash$ git log $nospace # Now THIS works great.
bash$ git log "$nospace" # This kind of works, here is a snippet:
# From git-log output:
Date: "2018-04-12"
Eca, por que a saída impressa tem aspas duplas agora? Parece que as aspas duplas são desnecessárias, elas não são removidas, são interpretadas como caracteres de aspas literais se e somente se não forem necessárias.
O que o Git está sendo passado como argumentos? Eu gostaria de saber como descobrir.
Para tornar as coisas mais complexas, escrevi um script Python usando argparse
isso apenas imprime todos os argumentos (como Bash os interpretou, portanto, com literais de aspas duplas em que Bash pensa que fazem parte do argumento e com palavras agrupadas ou não agrupadas como Bash achar melhor), e o argparse
script Python se comporta de maneira muito racional. Infelizmente, acho que argparse
pode estar silenciosamente corrigindo um problema conhecido com o Bash e, assim, obscurecendo as coisas bagunçadas que o Bash está passando para ele. Isso é apenas um palpite, não faço ideia. Talvez o git-log esteja estragando secretamente o que o Bash está passando para ele.
Ou talvez eu simplesmente não saiba o que está acontecendo.
Obrigado.
Edição editada: Deixe-me dizer isso agora, antes que haja respostas: eu sei que talvez eu possa usar aspas simples ao redor da coisa toda e depois não escapar das aspas duplas. Na verdade, isso funciona um pouco melhor para o meu problema inicial usando o git-log, mas eu testei em alguns outros contextos e é praticamente igualmente imprevisível e não confiável. Algo estranho está acontecendo ao citar dentro de variáveis. Eu nem vou postar todas as coisas estranhas que aconteceram com aspas simples.
Edit 2 - Isso também não funciona: eu só tive essa ideia maravilhosa, mas não funciona:
bash$ mydate="--date=format:%Y-%m-%d\ T%H"
bash$ git log "$mydate"
# Git log output has this:
Date: 2018-04-12\ T23
Portanto, ele não possui aspas, mas possui um caractere de barra invertida literal na string de data. Além disso, git log $mydate
sem erros de cotação, o espaço de barra invertida na variável