Użycie ukośnika odwrotnego do znaków w cmd.exe (polecenie runas jako przykład)

6

Widzę, że daszek to udokumentowana postać ucieczki.

Ale mam przykład pokazujący, że w przypadku znaku podwójnego cudzysłowu ^nie działa i musisz go użyć\

C:\>runas /user:Administrator "cmd /k dir \"%userprofile%\""

Dlaczego tak jest i gdzie jest to udokumentowane?

barlop
źródło

Odpowiedzi:

4

Jeden z przykładów RUNAS /?pokazuje tę składnię. Daszek jest znakiem ucieczki, CMD.EXEale w systemie Windows poszczególne programy mogą dowolnie implementować własne znaki ucieczki i globowanie.

Dennis Williamson
źródło
ciekawe .. i btw .. co robi cmd.exe z nieoznaczonymi cudzysłowami na końcu? czy to je zatrzymuje, jeśli tak, dlaczego ... Czy to je usuwa ... jeśli tak, to dlaczego były potrzebne?
barlop
@barlop: Zobacz odpowiedź Michaela .
Dennis Williamson
1
czy jesteś pewien, że \ "jest interpretowany przez runas, a nie przez cmd.exe? kompiluje to wc pastebin.com/28Q2Wxxr do w.exe Porównaj a) w" aa "b) w \" aa \ "c) w ^" aa ^”Zauważ, co się dzieje z pensjonatów w szczególności myślę, że to \ cmd powłoki traktując jako znak ucieczki..
barlop
chociaż nie interpretował go cmd.exe, to nie jest to również program, ale środowisko wykonawcze, które dzieli argumenty. nie jestem pewien, czy ktoś mógłby nazwać ten program swobodą jego implementacji. bardziej jak sposób, w jaki kompilator go zaimplementował, lub sposób, w jaki kompilator zaimplementował go dla programów. wszelkie programy napisane w przypuszczam, ms visual c, parsowałby argsv „soly” msdn.microsoft.com/en-us/library/a1y7w461.aspx
barlop 28.08.13
8

Cmd, \czy nie uciec ". Oto szybki dowód i wyjaśnienie:

  1. Uruchom echo "" & echo 1. ( &jest specjalnym znakiem w cmd, left & rightoznacza „uruchom, lefta następnie uruchom” right). Widzimy oba echo ""i echo 1są uruchamiane pomyślnie.

  2. Następnie uruchom echo " & 1234. Widzimy, że wynik jest " & 1234. Jest tak, ponieważ otwarcie "nie zostało zamknięte, a zatem wszystko po nim jest interpretowane jako ciąg znaków, w tym specjalny znak &.

  3. Uruchom echo "\" & 1234.

    • Jeśli \uniknie tego ", otwarcie "nie zostanie zamknięte, a znaki & 1234zostaną zinterpretowane jako część łańcucha.

    • Jeśli \nie następuje ucieczka ", że po "zamknie ciąg i & 1234będzie nie należy interpretować jako części łańcucha.

    W wyniku nie widzimy & 1234interpretacji jako części ciągu. Dowodzi to, że \nie udało mu się uciec ".

Co więc ucieka "w cudzysłowach za przekazywanie argumentów? Chociaż ^będzie działał poza cytatami (łatwo to sprawdzić za pomocą echo ^" & echo 1), nie uchodzi cytatom w cudzysłowie.

Rzeczywiście, w jaki sposób możemy uzyskać coś tak prostego jak echo """ & echo 1praca?

^Char? ... Nie, echo "^"" & echo 1wyniki "^""i nie """.

Co z "samym char? ... Nie, echo """" & echo 1 wyniki """"i nie """.

Faktem jest, że nie ma nic, co ucieknie "w cudzysłowie do przekazywania argumentów . Możesz się nad tym zastanawiać przez kilka lat i nie znaleźć rozwiązania. To tylko niektóre nieodłączne ograniczenia skryptów cmd.

Dobra wiadomość jest taka, że ​​najprawdopodobniej nigdy nie spotkasz się z sytuacją, w której musisz to zrobić. Jasne, nie ma sposobu, aby dostać się echo """ & echo 1do pracy, ale to nie jest taka wielka sprawa, ponieważ jest to po prostu wymyślony problem, którego prawdopodobnie nigdy nie spotkasz.

Rozważmy na przykład runas. Działa dobrze bez konieczności ucieczki "w cudzysłowie, ponieważ runaswiedział, że nie ma na to sposobu i wprowadził wewnętrzne poprawki, aby obejść ten problem. runaswymyślił własne reguły analizy ( runas /flag "anything even including quotes") i nie interpretuje argumentów cmd w zwykły sposób. Oficjalna dokumentacja tej specjalnej składni jest dość rzadka (lub nie istnieje). Oprócz /?i helpjest to głównie metoda prób i błędów.

Pacerier
źródło
4

\Znak sprawia, że interpreter interpretować następny znak jako znak zamiast na identyfikatorze .

Widać to również w kodzie:

"Hello \"World\""

jest to interpretowane jako

Hello "World"

w twoim przykładzie, aby przekazać argumenty cmd, musi być ujęte w „”. Ale ponieważ argumenty cmdzawierające „(a to by zakończyło załącznik) są dołączane przez \. Gdyby„ ”nie byłoby tam, /k dir \"%userprofile%\"interpretowane byłyby jako argumenty przeciwko runas, a nie cmd.

Powodem, dla którego zawierają% userprofile%, jest to, że jest to zmienna środowiskowa i zostanie zastąpiona tekstem, który może zawierać spacje, co (z tego samego powodu, co powyżej) spowodowałoby, że argument byłby cmdniepoprawny.

Domyślna
źródło
Wydaje mi się, że RunAs „potrzebuje” cytatów, gdy ten drugi parametr, parametr programu, ma spację. W przeciwnym razie uważa, że ​​otrzymuje więcej parametrów niż jest w rzeczywistości. Teoretycznie runy mogły zostać napisane (mam na myśli kodowanie), aby doprowadzić je do końca, ponieważ jeden parametr nie wymaga cudzysłowów. W kontraście do tego. cmd.exe np. cmd / c dir ab Który przyjmuje parametr -dir a b- jako jeden parametr.
barlop
Ponadto, bardziej złożona kwestia, wydaje mi się, że runy mogłyby się obejść bez \ "Ale nie mogą, ponieważ traktuje to jako„ początek i następny "jako koniec. Gdyby po prostu wziął większość z zewnątrz jako początek i koniec, wtedy nie musiałby być środkowymi \ "np. nawet nieprzyjemnie wyglądającą linią, taką jak C: \> runas / user: Administrator" runas / user: Administrator \ "cmd / k dir \"% userprofile% \ „\” „Gdyby to wszystko” i nie \ ”, teoretycznie nadal można to przetworzyć. Ale nie z powodu sposobu, w jaki napisano runy.
barlop
@barlop: Nie uważaj tego cmdza argument za runami, bo tak nie jest. Argumentem dla Runas jest cmd /k dir \"%userprofile%\". Nie mam teraz czasu, ale daj mi kilka godzin i powinienem być w stanie wytłumaczyć ci prosty program w C ++ oraz sposób, w jaki te programy interpretują argumenty. Myślę, że byłoby to bardziej jasne. Zatem odpowiedź na pewno się zmieni
domyślnie
Właściwie to rozumiem i po prostu nie było jasne. Jestem świadomy głównej metody i argsv. Słyszałem, że biorą wszystkie argumenty w swoim pierwszym elemencie? czy to prawda? Jeśli chodzi o moją wzmiankę o cmd.exe, istnieje dwuznaczność, czy mam na myśli cmd.exe w tym wierszu, czy zewnętrzny cmd.exe, w którym wiersz jest zapisany. Jedyny raz wspominałem cmd.exe w tym, co napisałem w tych komentarzach, było cmd / c dir ab I mam rację, że -dir a b- ma 1 parametr. Ale powiedziano mi (nie wiem, czy poprawnie), że wszystkie programy systemu Windows pobierają wszystkie argumenty jako 1 ciąg, prawdopodobnie argsv [0], a następnie sami je dzielą
barlop,
1
@Michael, jeśli chcesz to w formularzu Dlaczego ... mógłbym zapytać. Dlaczego cmd / c dir ab jest interpretowane jak cmd / c "dir a b" Podczas gdy w runach parametr programu (patrz runas /?) Chce cytatów. Myślę, że runy można łatwo zakodować, aby ich nie chciały. Ponieważ wydaje mi się teoretycznie, nie powinien ich potrzebować.
barlop