za pomocą xargs do cd do katalogu

28

Teraz czuję się jak idiota. Dlaczego to nie działa?

echo "/some/directory/path" | xargs -n1 cd
Ian Lotinsky
źródło

Odpowiedzi:

22

Potok uruchamia xargs w podprocesie, a xargs uruchamia cd w podprocesie. Zmiany w podprocesie nie są propagowane do procesu nadrzędnego.

Ignacio Vazquez-Abrams
źródło
To ma sens. Dzięki za pomoc dla systemu UNIX.
Ian Lotinsky
3
Możesz uzyskać pożądany efekt, używając cudzysłowów: cd `echo "/some/directory/path" | cut -d\ -f1` (Zauważ, że dodałem „cut”, aby podzielić na spacje i złapać pierwszy element, tak jak robi to xargs)
Slartibartfast
5
W rzeczywistości xargsnie można go uruchomić, cdponieważ z konieczności jest on wbudowany w powłokę i xargsmoże uruchamiać tylko pliki wykonywalne wolnostojące. Jednak to, co powiedziałeś, jest prawdą o podprocesach.
Wstrzymano do odwołania.
/ usr / bin / cd jest zdecydowanie wolnostojącym udokumentowanym poleceniem Uniksa, przynajmniej w systemie Solaris.
jlliagre
Używanie @Slartibartfast do automatycznie generowanych ścieżek: cd `port file libcudd | sed -e 's/\/Portfile//'` (zwykle długie, których nie chcesz obsługiwać ręcznie, jak na przykład lokalizacja portfela MacPorts).
Ioannis Filippidis,
23

Polecenie cdjest wbudowane, ponieważ informacje o bieżącym katalogu są powiązane z procesem i tylko wbudowana powłoka może zmienić bieżący katalog działającej powłoki.

Istnieją dwa problemy z twoim kodem:

  1. xargsnie można uruchomić, cdponieważ cdjest to wbudowane polecenie i xargsmoże uruchamiać tylko pliki wykonywalne.
  2. Nawet jeśli uruchomisz cdpodproces wywoływany z xargs, nie będzie to miało żadnego wpływu na proces nadrzędny, jak wyjaśniono powyżej.

Rozwiązaniem jest uruchomienie podpowłoki, wewnątrz niej uruchom, cda następnie możesz wykonywać polecenia w nowym bieżącym katalogu.

ls | xargs -L 1 bash -c 'cd "$0" && pwd && ls'
parpa
źródło
W ls | xargs ...tym przykładzie nie ma sensu . Powinno to mieć wartość $0, na przykładecho "/some/directory/path" | xargs -L 1 bash -c 'cd "$0" && pwd && ls'
mądry
IMO lepszym rozwiązaniem byłoby: ls | xargs -L 1 -I @@ bash -c 'cd @@ && pwd && ls'
Roman M