Podczas pisania cd..
bez spacji między cd
i ..
wiersz polecenia systemu Windows z przyjemnością przełączy się do folderu nadrzędnego. Czy istnieje wyjaśnienie tego zachowania? Polecenie nie ma standardowego formatucommand<space>arguments
Ponadto, dlaczego nie zapewnia to spójnych wyników?
windows
command-line
command-line-arguments
Jonas Köritz
źródło
źródło
dir/a
podobną składnię VMS.cd c:\program files
bez cudzysłowów i nadal działacd..
działa Ponieważ Microsoft miał problem z jawnym uruchomieniem go.cd
to polecenie wbudowane w interpreter poleceń systemu Windows, a Microsoft może zmusić ich interpretera do zrobienia tego, co chce. (Jako kolejny przykładcd
nie trzeba też cytować katalogów ze spacjami w nazwie).Odpowiedzi:
Jak zauważają niektóre inne odpowiedzi / komentarze, pomysł, że po poleceniu musi być spacja, jest nieprawidłowy. Dobrze znanym przykładem jest to, że po poleceniu możesz wpisać ukośnik bez potrzeby wstawiania spacji.
Istnieje jednak inne zachowanie, które jest nieco mniej zrozumiałe i pozwala „
cd..
” o które pytasz. Takie zachowanie pozwala również na działanie „cd\
”.Opisane zachowanie jest spójne dla wszystkich poleceń wewnętrznych interpretera wiersza poleceń. Jeśli masz określone symbole, w tym kropkę, ukośnik lub ukośnik odwrotny, sprawdzane są wcześniejsze znaki, aby sprawdzić, czy są one poleceniem wewnętrznym powłoki „interpretera wiersza poleceń” (CMD.EXE lub jej poprzednika COMMAND.COM ).
Można to zrobić przed sprawdzeniem, czy słowo może odnosić się do pliku lub podkatalogu. Dotyczy to
cd
polecenia. Tragicznie, gdy tworzyłem próbkę, stwierdziłem, że tak się nie dzieje zcopy
poleceniem, więc wyniki są niespójne: niekoniecznie są takie same dla wszystkich poleceń wewnętrznych. Nie kontynuować przeszukiwanie również Porównaj (dużo) Inne komendy wierszdel
idir
tak po prostu sugerują, że jest niezwykle ostrożny, jeśli starają się polegać na tym, co dzieje się bez przestrzeni.Teraz pytanie dotyczy także polecenia echa : To niezwykły wyjątek, ponieważ moim zdaniem
echo.
jest dość dobrze znany ekspertom DOS. To prawdopodobnie zostało udokumentowane. Zachowanie, przynajmniej w CMD Win7 , jest takie, że jeśli polecenie zaczyna się od „echo.
”, to pierwszy okres jest ignorowany. Tak więc „echo..hi
” zamienia się w wynik „.hi
”. Powodem tego jest to, żeecho.
można użyć „ ” do wydrukowania pustej linii. W przeciwieństwie do Unixa możesz to zrobić po prostu uruchamiając polecenie „echo
” samodzielnie. Jednak w systemie DOS samo uruchomienie polecenia „echo
” spowoduje wyświetlenie bieżącego ustawienia „ echa ”. Podobnie DOS traktuje „Echo *Off*
” i „Echo *On*
„jako specjalne wartości, które zmieniają bieżące ustawienie echa. Jeśli rzeczywiście chcesz wydrukować słowo„Off
”, to„Echo.Off
”załatwia sprawę (przynajmniej w przypadku wystarczająco najnowszych wersji interpretera wiersza poleceń CMD Microsoftu .)Tak więc przynajmniej
echo
polecenie ma częściowo uzasadnione wytłumaczenie. Jeśli chodzi o pozostałe polecenia, myślałem, że polecenia wewnętrzne mają priorytet. Jednak gdy próbowałem wykonać kilka testów, okazało się, że jest to raczej niespójne. Pokazuję to na kilku przykładach, które tutaj udokumentowałem.Oto kilka przykładów. Użyłem wiersza polecenia z podwyższonym poziomem uprawnień, aby UAC nie niepokoił się tym, że piszę do katalogu głównego. Dokonano tego przy pomocy CMD.EXE systemu Microsoft Windows 7. Podejrzewam, że zachowania mogą być inne w przypadku innych wersji, takich jak COMMAND.COM ze starszych wersji MS-DOS lub oprogramowania wydanego przez inne firmy (COMMAND.COM DR-DOS).
(Ta odpowiedź jest już dość długa, więc nie uwzględniam poleceń, aby wyczyścić cały bałagan, który popełniłem w moim systemie plików. Jest trochę drobnego czyszczenia, ale niewiele).
Oto przykład, który dowodzi, że polecenie wewnętrzne tworzy pierwszeństwo. (Wykazuję również dość mało znaną umiejętność używania podwójnego dwukropka, aby skutecznie być komentarzem, co również działa dobrze w plikach wsadowych. Technicznie w plikach wsadowych jest przetwarzany jako etykieta, do której GOTO nie może uzyskać, i kończy się jest szybszy niż polecenie REM).
Oto przykład pokazujący, że kopia z pełną ścieżką nie używa tego samego pierwszeństwa (faworyzowanie wewnętrznego polecenia) jak cd, gdy nie jest używane rozszerzenie:
Moje wczesne ustalenia wykazały, że wyniki te pokazują, że powłoka wiersza poleceń daje pierwszeństwo:
To wyraźnie pokazuje, że zachowanie nie jest spójne między poleceniem kopiowania (z pełną nazwą pliku wraz z rozszerzeniem) a poleceniem cd (bez rozszerzenia jako części nazwy katalogu). Podczas korzystania z ukośnika odwrotnego polecenie kopiowania (z pełnym rozszerzeniem nazwy pliku) najpierw sprawdzi system plików, ale polecenie cd nie (jeśli katalog nie zawiera rozszerzenia).
(Aktualizacja: Na początku myślałem, że niespójność była oparta na różnych zachowaniach między programami. Później odkryłem, że niespójność istniała, ale była spowodowana bardziej z podanych parametrów.)
W rzeczywistości nawet te pociski nie są do końca dokładne, chociaż zdawałem się demonstrować każdą konkretną rzecz, którą właśnie powiedziałem. Problem polega na tym, że lista punktorów nie jest wystarczająco precyzyjna, aby była całkowicie dokładna. (Pozostawiłem rzeczy nieprecyzyjne, aby te punkty punktowe można było stosunkowo łatwo porównać i stosunkowo łatwo sprawdzić).
Jednak, aby być bardziej dokładnym, pierwszy punktor powinien wskazać, że powłoka wiersza poleceń daje pierwszeństwo:
Poniższe wykaże, dlaczego wprowadzam to rozróżnienie:
(Zauważ, że ostatnie polecenie kopiowania szukało pliku o nazwie \ needext , ponieważ użyto wewnętrznego polecenia kopiowania . Plik \ needext.bat został utworzony tylko po to, aby łatwo pokazać, że nigdy nie był używany przez wiersze poleceń zawierające słowo kopiuj .)
W tym momencie ustaliłem pewną niespójność (z zachowaniem się polecenia kopiowania ), gdy używany jest ukośnik odwrotny ...
Następnie pokażę, że istnieje pewna spójność między tymi poleceniami. (Więc istnieje spójność ... um ... czasami. Możemy mieć tylko spójność, niekonsekwentnie.) Następnie pokażę, że polecenie cd zachowuje się raczej jak polecenie kopiowania, gdy używana jest kropka. Polecenie kopiowania używa polecenia wewnętrznego, podobnie jak polecenie cd .
Tak więc, podczas początkowej sesji testowej, która skupiała się głównie na komendach cd i kopiowania (z pewnym dodatkowym użyciem md i odrobiną del ), jedynym czasem, kiedy naprawdę mieliśmy system plików na pierwszym miejscu, było polecenie kopiowania , a następnie system plików miał priorytet tylko przy użyciu pełnej ścieżki.
Po kolejnej recenzji okazało się, że polecenie cd również przyznało pierwszeństwo systemowi plików podczas używania rozszerzenia. Przynajmniej oznacza to, że polecenia wewnętrzne są traktowane bardziej spójnie ze sobą. Oznacza to jednak również, że otrzymujemy różne zachowanie w zależności od nazw obiektów systemu plików (plików lub katalogów). Wygląda na to, że w zachowaniu jest wykorzystywana naprawdę, bardzo niejasna logika wewnętrzna. Dlatego liczenie na takie zachowanie w różnych systemach operacyjnych jest czymś, co prawdopodobnie uważałbym za niebezpieczne .
źródło
ipconfig
na przykład też działa.IPCONFIG/ALL
. Jednak nie o tym mówiłem. „ Zachowanie, które opisujesz ” (w swoim pytaniu) to zachowanie polegające na umieszczeniu kropki bezpośrednio po nazwie polecenia. Jeśli piszę,IPConfig.
pojawia się błąd związany z brakiem polecenia. Podobnie (chociaż nie jest to związane z opisywanym zachowaniem), jeśli piszęIPCONFIG\ALL
, mogę uruchomić utworzony przez siebie.\IPCONFIG\ALL.BAT
plik niestandardowy . Więc/
nie są traktowani jak.
ani `\ 'copy.exe
lubcopy.com
w cmd. Nie działa - nie jest wykonywalny.ipconfig
, nie zgadzam się z twoim wnioskiem. To pytanie dotyczy tego, co wpisujesz na początku wiersza poleceń. Windows / DOS identyfikuje pliki wykonywalne według rozszerzenia nazwy pliku, więc nie można uruchomić programu o nazwie „ipconfig” bez rozszerzenia (w Windows, w przeciwieństwie do Uniksa, który na to pozwala). Jeśli chodzi o następny komentarz, nie wiem, kim jest „Calchas”. (Gdy podasz znak at, następujące są zazwyczaj pierwsze znaki użytkownika, które pojawiają się w innym miejscu strony.) Zgadzam się, uruchomienie „copy.exe
” spowoduje użycie wewnętrznegocopy
polecenia (i przekaże.exe
). (Możesz biegać.\copy.exe
)Zakładasz, że nazwa polecenia i jego argumenty muszą być oddzielone spacją, ale nie jest to prawdą. Dopóki wywoływanie może być jednoznacznie interpretowane, wywoływanie jest ważne.
W tym przypadku, pierwszy argument zaczyna się
.
i.
nie może być częścią nazwy poleceń, takcd
i..
po prostu analizowany jako dwa odrębne tokeny.Zwykle pierwszy argument zaczyna się od znaku alfabetu (np. Początku ścieżki), więc „wykrwawia się” w nazwie polecenia i powoduje błąd… ale to nie jest problem ze składnią. Jest semantyczny.
Ten sam efekt możesz zobaczyć w pracy z innymi poleceniami, w tym
echo
:W tym przypadku, mamy tylko dwa okresy, ponieważ sama komenda ma specjalną regułę , dzięki czemu następuje:
echo
lub, co za tym idzie, to:
wyświetla tylko pustą linię. To wygoda. Najwyraźniej został zaimplementowany poprzez zignorowanie wiodącego okresu w argumencie.
Hej, to jest DOS / Batch. Chcesz zdrowia psychicznego? :RE
źródło
cd..
cd..
:)alias cd..='cd ..'
.
i..
który pojawia się jako katalogi w każdym innym katalogu i, o ile wiem, nigdy nie miał na celu złapania więcej. Właściwie uważam, że ukryty model jako atrybut pliku jest czystszym projektem niż to, że domyślnie wynika z nazwy pliku..
na nazwy plików , co oznaczało, że nie mógł być częścią nazwy polecenia, dlatego musiał być częścią argumentu . Nawet jeśli DOS podzielił polecenie na argumenty, tak jak robią to powłoki uniksowe, nadal umieściłby znak.
po poleceniu w pierwszym argumencie, ponieważ nie ma sensu wstawiać niepoprawnego znaku w nazwie polecenia.cd..
Komenda jest poprawna i została zdefiniowana jak w pierwotnym interpreter poleceńcommand.com
, które później nazwanocmd.exe
.Interpretator poleceń wie, jak przetwarzać
cd..
, ponieważ.
jest to znak specjalny, podobnie jak\
.źródło
echo.
działa równie dobrze, co spowoduje wydrukowanie pustej linii..
nie jest upuszczany, ale dodaje się tylko spację.md.test
imd .test
oba tworzą katalog.test
. Wpisująccd.test
icd .test
przejdzie do katalogu.test
.Jest to hack kompatybilności wstecznej.
Interpretator wiersza poleceń został zaprojektowany tak, aby był kompatybilny wstecz z poleceniami oryginalnego interpretera poleceń MSDOS, który został zaprojektowany tak, aby był kompatybilny wstecz z interpreterem poleceń CP / M. Ani CP / M, ani MSDOS nie zezwalają na a
.
w nazwie pliku (było to interpretowane jako separator między dwiema częściami nazwy pliku, nazwą podstawową i rozszerzeniem). Oznaczało to, że (przynajmniej we wczesnych wersjach DOS) interpreter poleceń mógłby rozpoznać, że jeśli osiągnie „.” (lub w rzeczywistości jakikolwiek inny znak, który był niedozwolony w nazwie pliku), przekazał koniec nazwy polecenia i znalazł się w argumentach polecenia. Było to dość powszechnie stosowane zarówno w DOS, jak i CP / M - na przykład,dir/w
było to bardzo popularne polecenie, równoważnedir /w
znaczeniu wyświetlania listy plików w formacie poziomym.Dzisiaj, '.' może pojawić się w nazwach plików. Powoduje to pewne komplikacje w przetwarzaniu poleceń, ale powłoka nadal identyfikuje plik,
.
który nie jest częścią dokładnej nazwy pliku, jako początek argumentów. Jest to konieczne głównie dlatego, że miliony użytkowników przyzwyczaiły się do pisaniacd..
lub mają dużą liczbę plików wsadowych zawierających tęecho.
lub dowolną liczbę innych podobnych poleceń.źródło