Zawsze zastanawiałem się, dlaczego cd
nie jest programem, ale nigdy nie udało mi się znaleźć odpowiedzi.
Czy ktoś wie, dlaczego tak jest?
shell
command
cd-command
shell-builtin
AkshaiShah
źródło
źródło
cd
komenda unix była osobnym programem. Powłoka obchodzić go specjalnie w tym, że niefork
tylkoexec
. A kiedycd
to się skończy, wykona poleceniesh
. Nie wiem, czy to prawdziwa historia.chdir
syscall. źródła: v1 v5 v7 (pierwsza wersja z powłoką Bourne'a)cd
tym, co przeczytałem. Wyraźnie się myliłem co do tego aspektu, skoro @jlliagre podało szczegóły.Odpowiedzi:
cd
Polecenie modyfikuje „bieżący katalog roboczy”, prawda?„bieżący katalog roboczy” jest właściwością unikalną dla każdego procesu.
Gdyby więc
cd
był to program, działałby tak:cd foo
cd
rozpoczyna się procescd
proces zmienia katalog dla procesu cdcd
wyjścia procesoweźródło
cd
byłby to program, działałby tak, jak powinien”, powinien być „w przypadkucd
użycia go w zewnętrznej realizacji programu, działa on w ten sposób”.cd
oprócz tego, że jest wbudowaną powłoką, w rzeczywistości jest także programem w systemach operacyjnych zgodnych z POSIX. Oni muszą zapewnić niezależne pliki wykonywalne dla zwykłych narzędzi, jakcd
. Jest to na przykład miejsce w przypadku systemu Solaris , AIX , HP-UX i OSX .Oczywiście wbudowane narzędzie
cd
jest nadal obowiązkowe, ponieważ jego zewnętrzna implementacja nie zmienia bieżącego katalogu powłoki. To ostatnie może być jednak nadal przydatne. Oto przykład pokazujący, jak POSIX wyobraża sobie, jakcd
można użyć tego polecenia:W systemie POSIX ten oneliner zgłasza komunikat o błędzie dla wszystkich katalogów, do których nie wolno ci wchodzić
cd
. W większości dystrybucji Gnu / Linux nie wyświetla się ten komunikat o błędzie:Oto odpowiedź na pytanie „ Dlaczego cd nie jest programem? ” Jednego z oryginalnych współautorów Uniksa. Na bardzo wczesnej implementacji Uniksa
cd
(chdir
w tym czasie pisownia ) był programem zewnętrznym. Właśnie przestał działać nieoczekiwanie pofork
pierwszym wdrożeniu.Cytując Dennisa Ritchiego :
Źródło: Dennis M. Ritchie, „ Ewolucja uniksowego systemu podziału czasu ”, AT&T Bell Laboratories Technical Journal 63 (6), część 2, październik 1984, s. 1577–93
Strona podręcznika chdir dla Unix Version 1 (marzec 1971) stwierdza:
Ponieważ tworzony jest nowy proces do wykonania każdej komendy, chdir byłby nieskuteczny, gdyby został napisany jako normalna komenda. Jest zatem rozpoznawany i wykonywany przez Shell.
źródło
cd
plik wykonywalny, ale nie powinien nic robić (oprócz ewentualnego emitowania komunikatów o błędach, jeśli zostanie wywołany z niewłaściwymi argumentami). Dziwne.Ze wstępu do Bash ( Co to jest powłoka? ):
źródło
Na April Fool's w tym roku napisałem samodzielną wersję
cd
.Nikt nie żartuje. Westchnienie.
Każdy, kto nie jest pewien, czy
cd
musi to być wbudowane w powłokę, powinien ją pobrać, zbudować i wypróbować.Przeczytaj także jego stronę podręcznika. :)
źródło
/bin/cd
. Jeśli chcesz wziąć mój kod i zrobić z niego osobistą misję, możesz to zrobić.cd
Polecenie w powłoce nie może być oddzielny proces w systemie Unix ponieważ nie ma mechanizmu, aby zmienić bieżący katalog roboczy inny proces (nawet proces nadrzędny).Gdyby
cd
był to inny proces, musiałby zmienić bieżący katalog roboczy swojego rodzica (powłoki), co nie jest możliwe w Uniksie. Zamiast tegocd
jest specjalne wbudowane polecenie. Wywołania powłoki działają jakchdir()
ifchdir()
zmieniają własny bieżący katalog roboczy.Uwaga: jądro przechowuje numer i-węzła bieżącego katalogu roboczego dla każdego procesu. Proces potomny dziedziczy go po
cwd
rodzicu.źródło
cd jest wbudowanym poleceniem powłoki. Tak proste jak jest. Ten człowiek mówi wszystko. polecenie cd zmienia katalog roboczy dla wszystkich interpreterów i (w środowisku wątków) wszystkich wątków.
źródło
cd
jest wbudowany. Sugeruję przeczytanie odpowiedzi najwyżej ocenionych i zastanowienie się, w jaki sposób można poprawić odpowiedź.Myślę, że w ludziach brakuje jednej odpowiedzi: bieżący katalog to zmienna środowiskowa, którą każdy program może zmienić. Jeśli użyjesz polecenia „eksportuj”, aby wyświetlić listę bieżących zmiennych środowiskowych, będziesz mieć:
w twoich wynikach. Dlatego za pomocą polecenia „cd” chcemy po prostu zmodyfikować tę zmienną wewnętrzną. Myślę, że jeśli spróbujemy, możemy zmienić zmienną PWD dowolnego pty w powłoce, oczywiście. Lubić:
Ale myślę, że nie ma takiej potrzeby w normalnych przypadkach. Innymi słowy, korzystamy z pomocy bash (lub dowolnej powłoki), aby zmodyfikować zdefiniowaną zmienną wewnętrzną.
źródło
..
ścieżkę, a nie ścieżkę, od której ją zacząłeś:#include <stdlib.h>
int main(void) { chdir(".."); puts(getenv("PWD")); }
(Nawiasem mówiąc, powłoki C eksponują CWD jako% cwd.)#include <unistd.h>
int main(void) { char ac[99]; setenv("PWD", "/", 1); puts(getcwd(ac, sizeof(ac))); }
pokaże katalog, z którego uruchomiłeś program, a nie/
.$PWD
ma to znaczenie tylko dla powłoki Bourne'a. Jest to po prostu sposób, aby powłoka komunikowała coś, co zna skrypty powłoki, więc nie muszą dzwonić,pwd
aby to znaleźć. Każdy samodzielny program w zależności od wartości$PWD
będzie zawodny.