2008-12-10 16 views
50

Próbuję to zrobić:Jak radzić sobie z cytatów przy użyciu cmd.exe

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

Mam jednak problemy, które są w dół do sposobu w jaki działa cmd.exe. Jeśli czytasz pomoc dla niego, obsługuje on "znaki w specjalny sposób.Zobacz pomoc na końcu pytania.Tak, to nie działa poprawnie ... Zgaduję, cmd.exe paski niektóre cytaty, które sprawia, że oświadczenie źle sformułowane

mogę to zrobić skutecznie..?

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

Ale naprawdę muszę się pierwszy do pracy jest tam z dala wokół dziwnej przetwarzania cytując który używa cmd.exe Chcę go zachować wszystkie cytaty, ale wydaje się, że nie ma opcji, aby to zrobić.


Pomoc zaczerpnięta z danych wyjściowych: cmd /?

Jeśli/C lub/k jest określona, ​​wówczas dalszą część linii polecenia po przełącznik jest przetwarzane w linii polecenia, gdzie następujące logiki stosowanego do przetwarzania cytat (") postaci:

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

Kiedy próbuję równoważny przykład to działa bez/S. Skopiowałem plik c: \ windows \ system32 \ replace.exe do c: \ i zmieniłem nazwę kopii "rep lace.exe", aby zawierało w nim miejsce. zamień po wykonaniu bez parametrów daje 2 linie od 1 do stderr i od 1 do stdout. więc jest to fajny przykład. C: \> cmd/c "rep lace"> "a a a" <---, które działało tak samo jak bez cmd/c. Interesuje mnie, w jaki sposób cmd analizuje rzeczy, czy masz jakiś pomysł, dlaczego rozbieżność między twoim przykładem a moim przykładem? lub w jaki sposób mogę odtworzyć twój przykład? ta – barlop

+0

@barlop - Najpierw proszę się bardziej postarać. Dlaczego nie spróbujesz, aby twój przykład wyglądał bardziej jak mój? Stick replace w folderze w plikach programu, wpisz ".exe" na końcu nazwy i wypisz w pliku znajdującym się w folderze zawierającym spacje. Zobacz, co się wtedy stanie. –

+0

tutaj http://pastebin.com/raw.php?i=YtwQXTGN działa dobrze dla sprawy, którą dałeś – barlop

Odpowiedz

65

Ah. doh. Chyba już odpowiedział na moje własne pytanie.

Jeśli używasz/S, i zawinąć całość w cudzysłowie, to po prostu usuwa te zewnętrzne cytaty.

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

+1 Pomoc w 'cmd /?' Nie jest tak pomocna jak ta odpowiedź –

+0

Tak więc z użyciem przełącznika/S , zawijasz wszystkie pliki/wykonywalne ścieżki w cudzysłowach, a następnie całe polecenie w innym zestawie cytatów. Pracowałem dla mnie, dzięki! –

+2

Dobry panie. cmd /?pomoc jest warta mniej niż nic. To faktycznie zaciemniło tę bardzo prostą odpowiedź. –

9

Myślę, że przekonasz się, że twój przykład działa absolutnie dobrze, jak jest.

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

Mam powielana swoją przykładem 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:\> 

Powodem Twój przykład działa dobrze

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

i jak/dlaczego to działa WA tak, robi to, ponieważ> jest interpretowane jako specjalne przez host.exe Więc ta część cmd.exe /C "C:\Program Files\Somewhere\SomeProgram.exe" - jak sądzę - jest oceniana jako pierwsza. np. cmd/c nie wyświetla> i później.

cmd /? pokazuje 2 przypadki

Przypadek 1 i Przypadek 2. Twój przykład pasuje Case 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. 

można przetestować na pewno, że Twój przykład pasuje przypadek 1, bo jeśli dodać/s (bez dodawania lub więcej ofert wprowadzając dowolną zmianę do twojego przykładu poza dodawaniem/s), wtedy dostajesz inny wynik, ponieważ sprawia, że ​​twój przykład trafia przypadek 2. To dowodzi, że twój przykład jest zdecydowanie przypadkiem 1. I jednoznacznie spełnia wszystkie kryteria przypadku 1. Jeśli twoim przykładem był przypadek 2, a Ty dodałeś/aś, to nie miałoby to znaczenia.

Twoja odpowiedź jest interesująca, ponieważ pokazuje alternatywny sposób uzyskania wyniku, ale w przypadku 2. Dodając dodatkowe wyceny zewnętrzne i dodając/s.

Ale tak naprawdę, po dodaniu tych dodatkowych dodatkowych ofert, właśnie stworzyłeś przypadek 2, a dodanie do tego/s nie będzie miało znaczenia.

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:\> 

Przykład w swoim pytaniu działało dobrze

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

Twój alternatywę (z/s, a cytaty zewnętrznych) dajesz jako odpowiedź do uczynienia przykładową pracę, działa też dobrze

Chociaż Twoja odpowiedź, która jest alternatywą, może być uproszczona poprzez usunięcie/S, ponieważ jest już przypadek 2, więc dodanie/s nie spowoduje żadnej różnicy. Więc to poprawiłoby rozwiązanie przyjęte w odpowiedzi

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

Twój przykład którą opisano jako problem w swoim pytaniu, a rozwiązania, produkować ten sam dobry wynik. Ale przypuszczam, że jedna duża różnica (i nie jestem pewna, jak to przetestować), ale jedna różnica w sposobie działania twojego przykładu i sposób działania rozwiązania w twojej odpowiedzi jest, jak sądzę, w przypadku twojego przykładu, Hosting/wywoływanie cmd.exe wykonuje przekierowanie do pliku. Podczas gdy w przykładzie rozwiązania, wywoływany plik cmd.exe jest przekazywany przez hosta cmd.exe, a więc wywoływany program cmd.exe wykonuje przekierowanie. Oczywiście, twój przykład to sprawa 1, a twoje rozwiązanie jest poprawką, którą zrobiłeś (bardzo dobrze), aby działało w przypadku 2.

Mam nadzieję, że nie popełniłem błędu tutaj, być może. Ale twoje pytanie i odpowiedź pomogły mi objąć głowę, jak działa cmd, a zwłaszcza cmd/c!

Być może twój przykład był zbytnim uproszczeniem twojego rzeczywistego, a twój faktyczny zawiodł i potrzebował twojej poprawki. Jeśli Twój przykładowy przypadek byłby nieco bardziej złożony, na przykład, mając parametr do programu, który zajął się wycenami, wówczas nie powiedzie się Przypadek 1, a faktycznie potrzebujesz dodatkowych ofert (/ S nie zmieniłoby wyniku , więc nie byłoby konieczne/S, ponieważ po dodaniu tych potrzebnych cudzysłowów był już przypadek 2). Ale wydaje mi się, że przykład, który podałeś w swoim pytaniu, działa dobrze.

Dodany - A related Q i A What is `cmd /s` for?

+0

Bardzo szczegółowe śledztwo. Być może masz rację, uprościłem to pytanie trochę czasu po opublikowaniu tego. Widziałem, że to pytanie było często oglądane, więc pomyślałem, że spróbuję usunąć nieistotne szczegóły ... ale może były one istotne. Proszę spojrzeć na historię pytania, aby zobaczyć oryginał. –

+0

@ScottLangham wygląda na to, że oryginał może mieć również uproszczenie z "someprogram" i "folder zawierający spacje" i bez parametru "someprogram". Dokładnie 2 cytaty przed przekierowaniem. Myślę, że jeśli twój "jakiś program" miałby parametr z cytatami, a następnie przekierowany, wtedy trafiłby do przypadku 2 opisanego w cmd /? I potrzebowałby innych ofert. (choć nadal nie potrzebuje/S). Ale twój przykład, który wydaje się być nawet w oryginale, cmd/c "jakiś program"> ... To wciąż pasuje do przykładu 1 i działa dobrze. – barlop

+0

@ScottLangham Jeśli przypadkowo dodano trzeci cytat przed przekierowaniem (co może się zdarzyć w sytuacji programowej z wyciętymi cudzysłowami, ponieważ może to wyglądać skomplikowanie), to spowodowałoby to również przypadek 2 (jako byłoby więcej niż 2 cytaty), a następnie potrzebowałbyś innych cytatów, aby zachowywać się właściwie. (choć nadal nie ma/s, as/s ma tylko sprawić, że sprawa 1 przejdzie do przypadku 2 i nie zmieni zachowania tego, co już jest w przypadku 2). – barlop

Powiązane problemy