Usiłuję uzyskać cd
nazwę katalogu przekierowanego do niej z innego polecenia. Żadna z tych metod nie działa:
$ echo $HOME | cd
$ echo $HOME | xargs cd
Działa to:
$ cd $(echo $HOME)
Dlaczego pierwszy zestaw poleceń nie działa i czy istnieją inne, które również zawodzą w ten sposób?
shell
io-redirection
pipe
cd-command
Jhonathan
źródło
źródło
Odpowiedzi:
cd
nie jest poleceniem zewnętrznym - jest to wbudowana funkcja powłoki. Działa w kontekście bieżącej powłoki, a nie, jak to robią polecenia zewnętrzne, w kontekście rozwidlenia / wykonania jako osobny proces.Trzeci przykład działa, ponieważ powłoka rozwija zmienną i podstawianie poleceń przed wywołaniem
cd
wbudowanego, dzięki czemucd
otrzymuje wartość${HOME}
jako argument.Systemy POSIX zrobić mają binarny
cd
- na moim komputerze FreeBSD, to co/usr/bin/cd
, ale to nie to, co myślisz. Wywołanie pliku binarnegocd
powoduje, że powłoka rozwidla / wykonuje plik binarny, co faktycznie zmienia katalog roboczy na przekazywaną nazwę. Jednak gdy tylko to zrobi, binarne wyjście, a proces fork / exec'd znika, wracając do twojej powłoki, która wciąż znajduje się w katalogu, w którym była przed uruchomieniem.źródło
cd
polecenia zewnętrznego ?cd
nie odczytuje standardowego wejścia. Dlatego twój pierwszy przykład nie działa.xargs
potrzebuje nazwy polecenia, czyli niezależnego pliku wykonywalnego.cd
musi być wbudowanym poleceniem powłoki i nie miałoby żadnego efektu (oprócz sprawdzenia, czy można przejść do tego katalogu i potencjalnych skutków ubocznych, jakie może on mieć w przypadku katalogów automatycznych), gdyby był plikiem wykonywalnym. Dlatego twój drugi przykład nie działa.źródło
Oprócz istniejącej dobrej odpowiedzi, warto również wspomnieć, że potok przygotowuje nowy proces, który ma swój osobny katalog roboczy. Dlatego próba zrobienia tego nie zadziała:
Dlatego nie będziesz w folderze / po powrocie powłoki z tego polecenia.
źródło
a | b
, nawet jeślia
ib
są wbudowane, co najmniej jeden wtedy nie działa w procesie powłoki, ale nie ma gwarancji, który, który to jest. Na przykład w AT & Tksh
,zsh
lubbash -O lastpipe
,b
prowadzony jest w obecnym procesie powłoki, dzięki czemu kod będzie można dostać się do / tam.Oprócz podanych już poprawnych odpowiedzi: Jeśli uruchomisz bash i chcesz dowiedzieć się, czym jest „polecenie”, takie jak cd , możesz użyć type
a dlaczego nie:
podczas gdy na przykład czas GNU jest zwykle zawarty w Twojej ulubionej dystrybucji:
Okej, dobrze, masz pomysł, a co to, u licha, jest?
Oto ręczny fragment kodu bash:
źródło
Jak powiedzieli inni, to nie zadziała, ponieważ
cd
jest to polecenie wbudowane w powłokę, a nie program zewnętrzny, więc nie ma żadnego standardowego wejścia, do którego można by coś potokować.Ale nawet gdyby zadziałało, nie zrobiłoby tego, co chcesz: potok spawnuje nowy proces i przekierowuje standardowe wyjście pierwszego polecenia na standardowe wejście drugiego, dlatego tylko nowy proces zmieniłby jego bieżące działanie informator; nie mogło to w żaden sposób wpłynąć na pierwszy proces.
źródło
read
jest zwykle (zawsze?) wbudowany w powłokę. To prawda, żecd
ignoruje standardowe wejście, ale nie wynika to z jego wbudowania.Inną opcją są backticks, które umieszczają stdout jednego polecenia jako argument wiersza poleceń drugiego polecenia i są bardziej przenośne niż
$(...)
. Na przykład:lub bardziej ogólnie;
Zauważ, że użycie backicksa zależy od powłoki do wykonania polecenia i podstawienia wyjścia w linii poleceń. Większość pocisków obsługuje to.
źródło
$(...)
działa. Nie wydaje mi się, że dobrym pomysłem jest polecanie odwrotnych stron, ponieważ mają one znacznie bardziej skomplikowane reguły cytowania i generalnie są bardziej podatne na błędy. (Patrz §3.5.4 „Zastępowanie poleceń” w Podręczniku użytkownika Bash .)$(...)
w jednym systemie, ale nie w innym?$(…)
. Systemy bez powłoki POSIX (tj. Z oryginalną powłoką Bourne'a) byłyby bardzo stare. Nawet systemy, w których/bin/sh
znajduje się powłoka Bourne'a i potrzebujesz innej ścieżki,/usr/xpg4/bin/sh
aby uzyskać powłokę POSIX, są obecnie rzadkością. Polecanie backtick'om każdemu, kto nie administruje starożytnym boxem unixowym, czyni z nich krzywdę.