2008-12-10 32 views
50

que estoy tratando de hacer esto:¿Cómo puedo lidiar con comillas cuando se utiliza cmd.exe

cmd.exe /C "C:\Program Files\Somewhere\SomeProgram.exe" > "C:\temp\Folder Containing Spaces\SomeProgram.out" 

Sin embargo, no tengo problemas que son hasta las obras de cmd.exe manera. Si lees la ayuda, maneja "caracteres de una manera especial. Mira la ayuda al final de la pregunta. Por lo tanto, esto no se ejecuta correctamente ... Supongo que cmd.exe elimina algunas citas que hacen que declaración mal formada

puedo hacer esto con éxito:..?

// quotes not required around folder with no spaces 
cmd.exe /C "C:\Program Files\Somewhere\SomeProgram.exe" > C:\temp\FolderWithNoSpaces\SomeProgram.out 

Pero, realmente necesito el primero en trabajar ¿hay distancia alrededor del procesamiento de las cotizaciones extraño que utiliza cmd.exe lo quiero para conservar todas las comillas, pero no parece haber una opción para que lo haga.


Ayuda tomada de la salida de: cmd /?

Si/C o/K se especifica, el resto de la línea de comando después el interruptor se procesa como una línea de comando, en donde la lógica siguiente se utilizada para procesar comillas (") personajes:

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 
     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. 
+0

cuando intento un ejemplo equivalente funciona sin/S. Copié c: \ windows \ system32 \ replace.exe en c: \ y renombré la copia "rep lace.exe" para que tenga espacio. replace cuando se ejecuta sin parámetros da 2 líneas una a stderr y una a stdout. así que es un buen ejemplo. C: \> cmd/c "rep lace"> "a a a" <--- que funcionaba igual que sin cmd/c. Estoy interesado en cómo cmd analiza las cosas, ¿tienes alguna idea de por qué la discrepancia entre tu ejemplo y mi ejemplo? o una forma en que puedo recrear tu ejemplo? ta – barlop

+0

@barlop - Por favor, intenta más duro primero. ¿Por qué no intentas que tu ejemplo se parezca más al mío? Sustituya Stick en una carpeta dentro de archivos de programa, escriba ".exe" al final del nombre y déjela en un archivo que se encuentre en una carpeta que contenga espacios. Vea lo que sucede entonces. –

+0

aquí http://pastebin.com/raw.php?i=YtwQXTGN funciona bien para el caso que proporcionó – barlop

Respuesta

65

Ah. plastilina. Creo que he respondido a mi propia pregunta.

Si utiliza/S, y envuelve todo el asunto entre comillas, sólo se elimina esas cotizaciones externas.

cmd.exe /S /C " do what you like here, quotes within the outermost quotes will be preserved " 
+10

+1 La ayuda dentro de 'cmd /?' No es tan útil como esta respuesta –

+0

Así que básicamente con el modificador/S , envuelve todas las rutas de archivos/ejecutables entre comillas, y luego todo el comando en otro conjunto de comillas. Trabajó para mí, gracias! –

+2

Buen señor. cmd /?la ayuda vale menos que nada. Realmente ofuscó esta respuesta muy simple. –

9

Creo que encontrará que su ejemplo funciona absolutamente bien tal como es.

cmd.exe /C "C:\Program Files\Somewhere\SomeProgram.exe" > "C:\temp\Folder Containing Spaces\SomeProgram.out" 

He reproducido el ejemplo aquí http://pastebin.com/raw.php?i=YtwQXTGN

C:\>cmd /c "c:\Program Files\my folder\my long program.exe" > "c:\temp\spaces are here\a.a" 

C:\>type "c:\temp\spaces are here\a.a" 
my long program.exe has run 

C:\> 

further example demonstrating it works with "my long program.exe", removing cmd /c, it operates fine too. 

C:\>"c:\Program Files\my folder\my long program.exe" > "c:\temp\spaces are here\ 
a.a" 

C:\>type "c:\temp\spaces are here\a.a" 
my long program.exe has run 

C:\> 



Another example, but with replace. replace with no parameters says "source path required" "no files replaced" 

C:\>replace > a.a 
Source path required 

C:\>type a.a 
No files replaced 

Exactly the same effect when they're in folders with spaces. 

C:\>cmd /c "c:\Program Files\my folder\replace.exe" > "c:\temp\spaces are here\r.r" 
Source path required 

C:\>type "c:\temp\spaces are here\r.r" 
No files replaced 

C:\> 

further demonstration with replace 
without cmd /c works fine too. 

C:\>"c:\Program Files\my folder\replace.exe" > "c:\temp\spaces are here\r.r" 
Source path required 

C:\>type "c:\temp\spaces are here\r.r" 
No files replaced 

C:\> 

La razón por la que su ejemplo funciona bien

cmd.exe /C "C:\Program Files\Somewhere\SomeProgram.exe" > "C:\temp\Folder Containing Spaces\SomeProgram.out" 

y cómo/por qué funciona la wa y lo hace, se debe a que> el intérprete lo interpreta como especial. Por lo tanto, esta parte cmd.exe /C "C:\Program Files\Somewhere\SomeProgram.exe", creo, se evalúa primero. es decir, cmd/c no ve el> y después.

cmd /? muestra 2 casos

casos 1 y 2. Su ejemplo se ajusta a la caja 1

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. 

Puede probar para asegurarse de que su ejemplo se ajusta el caso 1, porque si se agrega/s (sin añadir más citas o haciendo cualquier cambio a tu ejemplo que no sea agregar/s), entonces obtienes un resultado diferente, porque hace que tu ejemplo sea el caso 2. Así que eso prueba que tu ejemplo es definitivamente un caso 1. Y cumple claramente con todos los criterios del caso 1. Si su ejemplo fuera un caso 2, y agregó/s, entonces no haría ninguna diferencia.

Su respuesta es interesante porque muestra una forma alternativa de obtener su resultado, pero en el caso 2. Agregando comillas adicionales y agregando/s.

Pero en realidad, cuando agrega esas comillas adicionales externas, entonces acaba de convertirlo en un caso 2, y agregar una/s además de eso no hará la diferencia.

C:\>cmd /c "c:\Program Files\my folder\replace.exe" 
Source path required 
No files replaced 

C:\>cmd /s /c "c:\Program Files\my folder\replace.exe" 
'c:\Program' is not recognized as an internal or external command, 
operable program or batch file. 

C:\>cmd /c ""c:\Program Files\my folder\replace.exe"" 
Source path required 
No files replaced 

C:\>cmd /s /c ""c:\Program Files\my folder\replace.exe"" 
Source path required 
No files replaced 

C:\> 

El ejemplo de tu pregunta funcionó bien

cmd.exe /C "C:\Program Files\Somewhere\SomeProgram.exe" > "C:\temp\Folder Containing Spaces\SomeProgram.out" 

Su alternativa (con los/S y citas externas) le dan como respuesta a hacer el trabajo de ejemplo, funciona muy bien también

cmd.exe /S /C ""C:\Program Files\Somewhere\SomeProgram.exe" > "C:\temp\Folder Containing Spaces\SomeProgram.out"" 

Aunque su respuesta, que es una alternativa, en realidad se puede simplificar eliminando el/S porque ya está un caso 2, por lo que agregar/s no hará ninguna diferencia. Así que esto mejoraría la solución dada en su respuesta

cmd.exe /C ""C:\Program Files\Somewhere\SomeProgram.exe" > "C:\temp\Folder Containing Spaces\SomeProgram.out"" 

Su ejemplo, que usted ha descrito como un problema en su pregunta, y su solución, producen el mismo buen resultado. Pero una gran diferencia, supongo, (y no estoy seguro de cómo probarla), pero una diferencia en la forma en que funciona su ejemplo y la forma en que funciona la solución en su respuesta, es en el caso de su ejemplo, el hosting/invocando cmd.exe hace el redireccionamiento al archivo. Mientras que en el ejemplo de su solución, el cmd.exe invocado pasa el> por el cmd.exe del servidor, por lo que el cmd.exe invocado realiza la redirección. También por supuesto, su ejemplo es un caso 1, mientras que su solución es una enmienda que hizo (muy bien) para que funcione en el caso 2.

Espero no haberme equivocado aquí, puede que sí. Pero su pregunta y respuesta me ayudaron a entender cómo cmd y, en particular, cmd/c funciona.

Quizás su ejemplo fue una simplificación excesiva de su real, y la real falló y necesitó su enmienda. Si su caso de ejemplo hubiera sido un poco más complejo, por ejemplo, tener un parámetro para el programa que tomara citas, entonces fallaría el Caso 1, y de hecho necesitaría las comillas externas (/ S no cambiaría el resultado , entonces no sería necesario/S, ya que sería un caso 2 una vez que agregue las cotizaciones externas necesarias). Pero el ejemplo que dio en su pregunta realmente me parece que funciona bien.

Agregado - Un Q relacionado y A What is `cmd /s` for?

+0

Investigación muy detallada. Puede que tengas razón, simplifiqué la pregunta bastante después de publicarla. Vi que esta pregunta se estaba viendo mucho, así que pensé en intentar eliminar detalles irrelevantes ... pero tal vez fueran relevantes. Mire el historial de la pregunta para ver el original. –

+0

@ScottLangham parece que el original también puede haber tenido la simplificación excesiva con "algún programa" y "carpeta que contiene espacios" y ningún parámetro para "algún programa". Exactamente 2 citas antes de la redirección. Creo que si tu "algún programa" tuviera un parámetro con comillas y luego se redireccionara, llegaría al caso 2 descrito en cmd/?, y necesitaría comillas externas. (aunque aún no necesitaría/S). Pero su ejemplo, que parece estar incluso en el original, de cmd/c "algún programa"> ... Eso sigue siendo adecuado al Caso 1, y funciona bien. – barlop

+0

@ScottLangham Si hubiera agregado accidentalmente una tercera cotización antes de la redirección (que supongo que podría suceder en una situación de programación con comillas escapadas, ya que puede parecer complicado), entonces eso también causaría que sea un caso 2 (como habría más de 2 citas), y luego habría necesitado cotizaciones para que se comporte correctamente. (aunque todavía no/s, como/s es solo para hacer que un caso 1 vaya al caso 2, y no cambie el comportamiento de lo que ya es el caso 2). – barlop

Cuestiones relacionadas