Il secondo documento citato da Peter Mortensen nel suo commento alla risposta di Codesmith ha reso le cose molto più chiare per me. Quel documento è stato scritto da windowsinspired.com. Il collegamento è ripetuto: un modo migliore per comprendere le virgolette e l'escape degli argomenti della riga di comando di Windows .
Alcuni ulteriori tentativi ed errori portano alla seguente linea guida:
Evita ogni virgoletta doppia "
con un accento circonflesso ^
. Se si desidera che gli altri personaggi con un significato speciale per la shell dei comandi di Windows (ad esempio, <
, >
, |
, &
) devono essere interpretati come caratteri normali, invece, per poi fuggire con un accento circonflesso, anche.
Se vuoi che il tuo programma foo riceva il testo della riga di comando "a\"b c" > d
e reindirizzi il suo output al file out.txt , avvia il programma come segue dalla shell dei comandi di Windows:
foo ^"a\^"b c^" ^> d > out.txt
Se foo interpreta \"
come virgolette doppie letterali e si aspetta che le virgolette doppie senza caratteri di escape delimitino argomenti che includono spazi, allora foo interpreta il comando come se specifichi un argomento a"b c
, un argomento >
e un argomento d
.
Se invece pippo interpreta una virgoletta doppia doppia ""
come una virgoletta doppia letterale, avvia il programma come
foo ^"a^"^"b c^" ^> d > out.txt
L'intuizione chiave dal documento citato è che, nella shell dei comandi di Windows, un virgoletto senza caratteri di escape innesca il passaggio tra due possibili stati.
Alcuni ulteriori tentativi ed errori implicano che nello stato iniziale, il reindirizzamento (a un file o pipe) viene riconosciuto e un accento circonflesso ^
sfugge alle virgolette doppie e il segno di omissione viene rimosso dall'input. Nell'altro stato, il reindirizzamento non viene riconosciuto e un accento circonflesso non sfugge alle virgolette doppie e non viene rimosso. Facciamo riferimento a questi stati rispettivamente come "esterno" e "interno".
Se vuoi reindirizzare l'output del tuo comando, allora la shell dei comandi deve essere nello stato esterno quando raggiunge il reindirizzamento, quindi deve esserci un numero pari di virgolette doppie senza caratteri di escape (da accento circonflesso) prima del reindirizzamento. foo "a\"b " > out.txt
non funzionerà: la shell dei comandi passa l'intero "a\"b " > out.txt
a pippo come i suoi argomenti combinati della riga di comando, invece di passare solo "a\"b "
e reindirizzare l'output a out.txt .
foo "a\^"b " > out.txt
non funzionerà, perché il cursore ^
si incontra nello stato interno in cui è un carattere normale e non un carattere di escape, quindi "a\^"b " > out.txt
viene passato a foo .
L'unico modo in cui (si spera) funziona sempre è mantenere la shell dei comandi sempre nello stato esterno, perché allora il reindirizzamento funziona.
Se non hai bisogno di reindirizzamento (o altri caratteri con un significato speciale alla shell dei comandi), puoi fare a meno dei caret. Se foo interpreta \"
come virgolette doppie letterali, puoi chiamarlo come
foo "a\"b c"
Quindi foo riceve "a\"b c"
come argomenti combinati il testo e può interpretarlo come un singolo argomento uguale a a"b c
.
Ora, finalmente, alla domanda originale. myscript '"test"'
chiamato dalla shell dei comandi di Windows passa '"test"'
a myscript . Apparentemente myscript interpreta le virgolette singole e doppie come delimitatori di argomenti e le rimuove. È necessario capire cosa accetta myscript come virgolette doppie letterali e quindi specificarlo nel comando, utilizzando ^
per eseguire l'escape di tutti i caratteri che hanno un significato speciale per la shell dei comandi di Windows. Dato che myscript
è disponibile anche su Unix, forse \"
fa il trucco. Provare
myscript \^"test\^"
oppure, se non hai bisogno del reindirizzamento,
myscript \"test\"
myscript \"test\"