Jak sprawić, aby wiersz polecenia systemu Windows traktował pojedynczy cytat tak, jakby był podwójnym cytatem?


6

Mój scenariusz jest prosty - kopiuję próbki skryptów z książki online Mercurial i wklejam je w wierszu polecenia systemu Windows. Problem polega na tym, że próbki w książce używają pojedynczych cudzysłowów. Gdy w wierszu polecenia systemu Windows przekazywany jest ciąg pojedynczego cudzysłowu, ten ostatni nie rozpoznaje, że wszystko między pojedynczymi cudzysłowami należy do jednego ciągu.

Na przykład następujące polecenie:

hg commit -m 'Initial commit'

nie można wkleić tak, jak w wierszu polecenia, ponieważ ten ostatni traktuje 'Initial commit'jako dwa ciągi - 'Initiali commit'. Muszę edytować polecenie po wklejeniu i jest to denerwujące.

Czy można poinstruować wiersz polecenia systemu Windows, aby traktował pojedyncze cudzysłowy podobnie jak podwójne?

EDYTOWAĆ

Po odpowiedzi JdeBP przeprowadziłem trochę badań. Oto podsumowanie:

  • Punkt wejścia Mercurial wygląda tak (jest to program python):

    def run():
        "run the command in sys.argv"
        sys.exit(dispatch(request(sys.argv[1:])))
    
  • Stworzyłem więc mały program python, który naśladuje przetwarzanie wiersza poleceń używane przez mercurial:

    import sys
    print sys.argv[1:]
    
  • Oto dziennik konsoli Unix:

    [hg@Quake ~]$ python 1.py  "1 2 3"
    ['1 2 3']
    [hg@Quake ~]$ python 1.py  '1 2 3'
    ['1 2 3']
    [hg@Quake ~]$ python 1.py  1 2 3
    ['1', '2', '3']
    [hg@Quake ~]$
    
  • A oto odpowiedni dziennik konsoli Windows:

    C:\Work>python 1.py  "1 2 3"
    ['1 2 3']
    
    C:\Work>python 1.py  '1 2 3'
    ["'1", '2', "3'"]
    
    C:\Work>python 1.py  1 2 3
    ['1', '2', '3']
    
    C:\Work>
    

Widać wyraźnie, że system Windows nie traktuje pojedynczych cudzysłowów jako podwójnych. I to jest istota mojego pytania.


2
Albo oznaczyłeś to pytanie przez pomyłkę jako „Windows”, albo bardzo nie są to monity poleceń DOS .
— JdeBP

Uwaga: Twój program demonstracyjny dodaje pojedyncze cytaty na wyjściu, co być może trochę zaciemnia. Rzeczywiście system Windows n unix traktuje pojedyncze n podwójne cudzysłowy inaczej, patrz mój komentarz w odpowiedzi 2 JdeBP. To powiedziawszy, istnieją dwa sposoby, w jakie programy Windows mogą uzyskać wiersz poleceń (obszar po znaku zachęty) .1) GetCommandLine () 2) argsv. Argsv prawdopodobnie działa, wykonując GetCommandLine, a program, zanim dotrzesz do pierwszego wiersza funkcji głównej, podzieli go na argumenty oparte na tych regułach (w przypadku Ms Visual C) lub na podobnych regułach. msdn.microsoft.com/en-us/library/a1y7w461.aspx
— barlop

spróbuj skompilować ten pastebin.com/raw.php?i=4Bq7unGd i ten pastebin.com/raw.php?i=QkhBJWGb Oba w systemie Windows. Spróbuj wywołać je z argumentami i przekonaj się na podstawie wyników, jak traktują argumenty inaczej. Jeden używa GetCommandLine () jeden używa argsv. Sam system Windows nie rozdziela argumentów, nie wytwarza elementów argsv.
— barlop

Odpowiedzi:


6

Znaku cudzysłowu nie można zmienić w wierszu polecenia command.com. Możesz jednak użyć programu PowerShell, który przyjmuje zarówno pojedyncze, jak i podwójne cudzysłowy jako znaki cudzysłowu. Działają tak samo jak w powłokach uniksowych. Tzn. Pojedyncze cudzysłowy nie rozszerzają zmiennych, podczas gdy podwójne cudzysłowy będą.

Nadal możesz mieć problemy z cytatami w cytatach. Na przykład mam zainstalowanego na moim komputerze z systemem Windows truskawkowy perl. Kiedy uruchamiam perl -e 'print time, "\n" 'w PowerShell, widzę dane wyjściowe takie jak 1321375663SCALAR(0x15731d4). Muszę uciec od podwójnych cudzysłowów, aby działał zgodnie z oczekiwaniami:perl -e 'print time, \"\n\" '


1

Po pierwsze, wiersz poleceń nie jest interpretatorem poleceń. ( Wiersz polecenia jest wyświetlany przez interpreter poleceń. ) Po drugie, interpreter poleceń, wyświetlane monity i konsole Win32 nie mają z tym nic wspólnego.

W programach Win32 podzielenie wiersza poleceń na „słowa” - wielobajtowe łańcuchy znaków zakończone NUL, które programy w językach C i C ++ widzą jako przekazaną tablicę argumentów main()- należą do bibliotek wykonawczych tych programów. W systemach Unices i Linux powłoka dzieli słowa, ponieważ system operacyjny faktycznie działa w oparciu o tablicę ciągów argumentów. Nie dotyczy to Win32. W systemie Win32 sam system operacyjny działa w kategoriach ogona polecenia : pojedynczego długiego łańcucha, który wciąż zawiera wszystkie znaki cudzysłowu, które pierwotnie wpisano w wierszu polecenia. (Nie jest niektóre przetwarzanie wykonane na tym ogonie polecenia przez interpretera poleceń przed przekazaniem go do programu docelowego, ale nie jest to związane z dzieleniem słów.)

W twoim przypadku biblioteka środowiska wykonawczego dla twojego hgprogramu jest dostarczana z następującą komendą:

commit -m „Wstępne zatwierdzenie”

Biblioteka środowiska wykonawczego, z którą został skompilowany ten program, nie wie, że miałeś na myśli pojedynczy znak cudzysłowu, który ma być znakiem cudzysłowu, ponieważ nie jest to konwencja . Konwencja dotyczy tylko podwójnych cudzysłowów (i odwrotnych ukośników przed podwójnymi cudzysłowami).

Konwencja ta jest wbudowana w bibliotekę wykonawczą dostarczoną wraz z kompilatorem używanym do tworzenia programu. Jeśli chcesz zmienić konwencję, będziesz musiał ponownie połączyć każdy program, który chcesz uruchomić w ten sposób, ze specjalną własną biblioteką wykonawczą, która rozpoznaje również pojedyncze cudzysłowy. Oczywiście jest to niepraktyczne (chyba że są to wszystkie programy Cygwin).

O wiele bardziej praktyczne podejście polega na robieniu tego, co już robisz: rozpoznaj, że Windows nie jest Uniksem i odpowiednio dostosuj przykłady przed ich użyciem.


1
Trudno mi zrozumieć znaczenie twojej odpowiedzi. W każdym razie zaktualizowałem swoje pytanie.
— zaznacz

Nie wszystko zależy od czasu wykonywania, ponieważ mimo że program pobiera to wszystko za jednym razem, sam interpreter cmd interpretuje pojedyncze cudzysłowy inaczej niż podwójne. np. jeśli wpiszesz „&”, to & jest dosłowne, a „&” jest przekazany jako parametr, różni się od „&”, ponieważ ampersand- i będą traktowane jako specjalne i nie zostaną przekazane. Również cmd /? ma kilka reguł, które, jak przypuszczam, dotyczą interpretera cmd, a nie środowiska wykonawczego.
— barlop

0

Jestem pewien, że nie możesz edytować sposobu, w jaki DOS analizuje polecenia. Jest to nieodłączne od programowania podstawowego.

Jedynym rozwiązaniem, które mogę wymyślić, aby przyspieszyć, jest pozostawienie otwartego okna Notatnika i uruchomienie „Znajdź i zamień” - zastępując wszystkie pojedyncze cudzysłowy podwójnymi cudzysłowami. Następnie stamtąd kopiuj i wklej do DOS.


1
Nie wiem o 9X's command.com (przypuszczam, że to jest DOS! A 9X jest prawdopodobnie nadal dodatkiem do DOS), ale CMD.EXE NT nie jest DOS! DOS to system operacyjny. CMD.EXE to dodatek w systemie operacyjnym NT i nie będzie działał poza nim. Podałem -1 za nazwanie go DOS, bardzo amatorsko jest nazywać NTD.exe / „procesorem poleceń systemu Windows” „DOS”.
— barlop
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.