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?
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
@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. –
aquí http://pastebin.com/raw.php?i=YtwQXTGN funciona bien para el caso que proporcionó – barlop