windows cmd: problemi con for / f con un comando quotato con parametri quotati

for /f "delims=" %%a in ('"%systemRoot%\system32\find.exe" /?') do @echo %%a 

Sì, la linea precedente funziona. Non molto utile ma funziona. Ma provando a scrivere un file batch per rispondere ad un’altra domanda, ho affrontato qualcosa di simile

  for /f %%a in ('"%systemRoot%\system32\find.exe" /c /v "" ^< "c:\something.txt"') do @echo %%a for /f %%a in ('"%systemRoot%\system32\find.exe" /c /v "" "c:\something.txt"') do @echo %%a 

Restituiscono entrambe le righe precedenti The filename, directory name, or volume label syntax is incorrect

  for /f %%a in ('"%systemRoot%\system32\find.exe" /c /v "" ^< c:\something.txt' ) do @echo %%a for /f %%a in ('"%systemRoot%\system32\find.exe" /c /v "" c:\something.txt' ) do @echo %%a 

Entrambe le righe precedenti restituiscono The system cannot find the file specified

Non sono stato in grado di farlo funzionare, né scappare le virgolette, raddoppiarle, precedendo con i backslash, passare alle virgolette singole alle backquote e impostare l’opzione corrispondente in for comando, tutte le combinazioni che ho provato fallivano.

Se il comando da eseguire è quotato e prende argomenti quotati fallisce.

E sì, so che le virgolette che circondano il find non sono necessarie e, se rimosse, qualsiasi delle quattro righe precedenti funzionerà (ignorando l’output, le eliminazioni, i token)

Ma nel caso in cui le virgolette che racchiudono il comando siano davvero necessarie (e conosco sistemi in cui il comportamento di 8dot3name è disabilitato), c’è un modo per farlo funzionare? cosa mi manca qui?

Ecco due soluzioni.

1) circonda le virgolette doppie e rimuove il carattere di escape.
2) usa trova così com’è sul percorso.

 for /f %%a in ('""%systemRoot%\system32\find.exe" /c /v "" < "c:\something.txt""') do @echo %%a for /f %%a in (' find.exe /c /v "" ^< "c:\something.txt"') do @echo %%a 

Ha a che fare con l'avvio di un processo cmd extra per eseguire la riga di comando all'interno del comando for.

Curiosamente, questi tre comandi falliscono in modo diverso in un contesto ancora più semplice.

 for /f %%a in (' "c:\windows\system32\find.exe" /c /v "" something.txt ') do @echo %%a 

Il sistema non può trovare il percorso specificato.

 for /f %%a in (' "c:\windows\system32\findstr.exe" /n "." something.txt ') do @echo %%a 

Il nome della directory non è valido.

 for /f %%a in (' "c:\windows\notepad" "something.txt" ') do @echo %%a 

'c: \ windows \ notepad "" something.txt' non è riconosciuto come comando interno o esterno, programma eseguibile o file batch.

Quest'ultimo dà l'idea che le citazioni esterne vengono rimosse.

Windows 8.1 32 bit

Penso che il problema del preventivo sia descritto qui in cmd /? quando viene invocato un processo figlio:

 If /C or /K is specified, then the remainder of the command line after the switch is processed as a command line, where the following logic is used to process quote (") characters: 1. If all of the following conditions are met, then quote characters on the command line are preserved: - no /S switch - exactly two quote characters - no special characters between the two quote characters, where special is one of: &<>()@^| - there are one or more whitespace characters between the two quote characters - the string between the two quote characters is the name of an executable file. 2. Otherwise, old behavior is to see if the first character is a quote character and if so, strip the leading character and remove the last quote character on the command line, preserving any text after the last quote character. 

È un po ‘più semplice mettere il primo token dall’istruzione del ciclo for in un token senza virgolette.

 for /f "delims=" %%a in ( ' if defined OS "C:\my folder with spaces\consoleapp.exe" /param1:"value" ' )do @echo %%a