Questão Usando barra invertida para escapar de caracteres em cmd.exe (comando runas como exemplo)


Eu vejo que o cursor é o caractere de escape documentado.

Mas, eu tenho um exemplo mostrando que para o caracter de aspas duplas, ^ não funciona e você tem que usar \

C:\>runas /user:Administrator "cmd /k dir \"%userprofile%\""

Por que isso e onde está documentado?


4


origem




Respostas:


Um dos exemplos em RUNAS /? mostra essa sintaxe. O cursor é o caractere de escape para CMD.EXE mas no Windows programas individuais são livres para implementar seus próprios caracteres de escape e globbing.


4



interessante .. e btw .. o que é cmd.exe fazendo com as citações sem escape no final? isso os mantém, se sim, por que ... Ou os remove ... se sim, por que eles eram necessários em primeiro lugar? - barlop
@barlop: Veja o Michael responda. - Dennis Williamson
tem certeza de que "está sendo interpretado por runas e não por cmd.exe?" pastebin.com/28Q2Wxxr  para w.exe Compare a) w "a a" b) w \ "a a \" c) w ^ "a a ^" Observe o que acontece com b em particular. Eu acho que é o shell cmd tratando \ como um caractere de escape. - barlop
enquanto não foi o cmd.exe que o interpretou, também não é o programa, é o tempo de execução que divide args. Eu não tenho certeza se alguém poderia dizer que o programa está sendo livre para implementá-lo. mais como a maneira como o compilador o implementou, ou a maneira como o compilador o implementa para os programas. quaisquer programas escritos em suponho, ms visual c, iria analisar argsv "assim" msdn.microsoft.com/pt-br/library/a1y7w461.aspx - barlop


Em cmd, \ faz não escapar ". Aqui está uma prova rápida e explicação:

  1. Corre echo "" & echo 1. (& é um caracter especial em cmd, left & right significa correr left então corra right.) Podemos ver que ambos echo "" e echo 1 são executados com sucesso.

  2. Em seguida, corra echo " & 1234. Podemos ver que a saída é " & 1234. Isso é porque a abertura " não foi fechado, e, portanto, tudo depois é interpretado como uma string, incluindo o caracter especial &.

  3. Corre echo "\" & 1234.

    • E se \ foge do seguinte ", a abertura " não será fechado e os caracteres & 1234 será interpretado como parte da string.

    • E se \ não consegue escapar do seguinte ", aquele Segue " irá fechar a corda e & 1234 vai não ser interpretado como parte da string.

    Na saída, não vemos & 1234 interpretado como parte da string. Isso prova que \ não conseguiu escapar ".

Então, o que escapa " dentro de cotações para passagem de argumento? Enquanto ^ funcionará fora das aspas (facilmente comprovado via echo ^" & echo 1), não escapa citações entre aspas.

De fato, como podemos obter algo tão simples quanto echo """  &  echo 1 trabalhar?

o ^ Caracteres? ...Não, echo "^"" & echo 1 saídas "^"", e não """.

O que acontece com o " char em si? ...Não, echo """" & echo 1  saídas """", e não """.

O fato é que, não há nada que escape " dentro de citações para passagem de argumento. Você pode refletir sobre isso por um par de anos e chegar a nenhuma solução. Estas são apenas algumas das limitações inerentes do script cmd.

No entanto, a boa notícia é que você provavelmente Nunca se deparar com uma situação em que você precisa fazer isso. Claro, não tem como chegar echo """  &  echo 1 para trabalhar, mas isso não é tão importante, porque é simplesmente um problema artificial que você provavelmente nunca encontrará.

Por exemplo, considere runas. Funciona bem sem precisar escapar " entre aspas porque runas sabia que não há como fazer isso e fez ajustes internos para contornar isso. runas inventou suas próprias regras de análise (runas /flag "anything even including quotes") e não interpreta argumentos cmd do modo usual. A documentação oficial para essa sintaxe especial é bastante esparsa (ou inexistente). Além de /? e helpé principalmente tentativa e erro.


6





o \ sinal faz o intérprete interpretar o próximo sinal como um personagem em vez de um identificador.

Você também vê muito no código:

"Hello \"World\""

isto é interpretado Como

Hello "World"

no seu exemplo, a fim de passar os argumentos para cmd, precisa ser colocado em "". Mas desde os argumentos para cmd contém "(e isso terminaria o recinto) eles são anexados por \. Se o "" não estivesse lá, o /k dir \"%userprofile%\" teria sido interpretado como argumentos para runasnão para cmd.

A razão pela qual eles estão colocando o% userprofile% é porque esta é uma variável ambiental e será substituída por um texto que poderia conter espaços, que (pela mesma razão acima) faria o argumento para cmd incorreta.


3



Parece que o RunAs "precisa" de cotações quando o segundo parâmetro, o parâmetro do programa, tem um espaço. Caso contrário, acha que está sendo dado mais parâmetros do que é. Em teoria, as runas poderiam ter sido escritas (digo codificadas) para levar até o fim, como um parâmetro sem aspas necessárias. Em contraste com isso. cmd.exe, por ex. cmd / c dir a b Isso leva -dir a b- como um parâmetro. - barlop
Além disso, um ponto mais complexo, parece-me que runas poderiam ter feito sem \ "Mas não pode porque está tomando o" como começar e o próximo "como fim. Se ele apenas levou os mais externos como início e final, então não precisaria que os do meio fossem \ "eg mesmo uma linha de aparência desagradável como esta C: \> runas / user: Administrador "runas / usuário: Administrador \" cmd / k dir \ "% userprofile% \" \ "" Se fosse tudo "e não \", em seguida, teoricamente você ainda pode processá-lo. Mas não é assim por causa da maneira como runas foi escrito. - barlop
@barlop: não pense em cmd como o argumento para runas, porque não é. O argumento para runas é cmd /k dir \"%userprofile%\". Eu não tenho tempo agora, mas me dê um par de horas e eu deveria ser capaz de explicar um programa C ++ simples para você e como esses programas interpretam argumentos. Eu acho que seria mais claro. Assim, resposta obrigado a mudar - Default
Na verdade, eu posso entender e simplesmente não estava claro. Estou ciente do método principal e do argsv. Ouvi dizer que eles tomam todos os argumentos em seu primeiro elemento? isso esta certo? Quanto a mim mencionar o cmd.exe, há uma ambigüidade se quero dizer cmd.exe nessa linha, ou o outd cmd.exe em que a linha está escrita. A única vez que mencionei o cmd.exe no que escrevi nesses comentários, foi cmd / c dir ab E eu estou certo que -dir a b- é um parâmetro. Mas eu tenho dito (não sei se corretamente) que todos os programas do Windows obtêm todos os seus args como 1 string, presumivelmente argsv [0], então dividi-lo - barlop
@Michael, se você quiser, por que forma .. eu poderia perguntar. Por que é cmd / c dir a b interpretada como cmd / c "dir a b" Considerando que, com runas, o parâmetro do programa (veja runas /?) Quer aspas. Eu acho que as runas poderiam ter sido facilmente codificadas para não as quererem. Desde me parece que, teoricamente, não deveria precisar deles. - barlop