Czy istnieje sposób na wykonanie polecenia w innym katalogu bez potrzeby cd
? Wiem, że mogłem po prostu wchodzić cd
i cd
wychodzić, ale interesują mnie możliwości rezygnacji z dodatkowych kroków :)
Czy istnieje sposób na wykonanie polecenia w innym katalogu bez potrzeby cd
? Wiem, że mogłem po prostu wchodzić cd
i cd
wychodzić, ale interesują mnie możliwości rezygnacji z dodatkowych kroków :)
Odpowiedzi:
Nie wiem, czy to się liczy, ale możesz utworzyć podpowłokę:
$ (cd /var/log && cp -- *.log ~/Desktop)
Katalog jest zmieniany tylko dla tej podpowłoki, dzięki czemu unikasz pracy cd -
późniejszej.
$ (cd /var/log && cp *.log ~/Desktop)
. W ten sposób, jeśli katalog nie istnieje, nie są wykonywane dalsze polecenia.
Niektóre programy mają opcje, za pomocą których możesz im powiedzieć, aby sami chdir (2) (np. GNU tar 's -C
/ --directory
).
Jednak poza takimi programami coś będzie musiało zmienić . Mógłbyś napisać i użyć jakiegoś skompilowanego programu „binarnego” zamiast zmuszać powłokę do zrobienia tego, ale prawdopodobnie nie przyniosłoby to wiele korzyści.
W komentarzu w innej odpowiedzi podałeś przykład:
execindirectory -d /var/log "cp *.log ~/Desktop"
Ponieważ *.log
wzór jest rozszerzony przez samą (nie skorupkach cp ), coś będą musieli chdir do katalogu przed posiadające powłokę ocenić swoje polecenie.
Jeśli po prostu interesuje Cię unikanie konieczności „cofania dysku CD”, możesz użyć podpowłoki w celu odizolowania efektu płyty CD od działającej instancji powłoki.
(cd /path/to/dir && some command)
Możesz spakować to w funkcji powłoki. (Usunąłem -d
opcję z twojego przykładowego użycia, ponieważ nie ma sensu tego polecenia, jeśli katalog jest opcjonalny).
runindir() { (cd "$1" && shift && eval "$@"); }
runindir /var/log 'cp *.log ~/Desktop' # your example
runindir /var/log cp \*.log \~/Desktop # eval takes multiple args
runindir /var/log cp \*.log ~/Desktop # it is okay to expand tilde first
Nie podważam wartości odpowiedzi udzielanych przez innych ludzi, ale wierzę, że chcesz tego:
(cd /path/to && ./executable [ARGS])
Zwróć uwagę na pareny do wywołania cd
w podpowłoce.
Oto coś, co powinno pozwolić ci cd
wrócić tam, gdzie byłeś (używając Bash), ponieważ nie zapomnienie o tym wydaje się być celem pytania:
# Save where you are and cd to other dir
pushd /path/to/dir/that/needs/to/be/current/dir
run-your-command
# Get back where you were at the beginning.
popd
(EDYCJA: nieco krótsza wersja, dzięki @ Random832)
pushd other-dir
, zamiastpushd .; cd other-dir
Niestety twój przykład:
execindirectory -d /var/log "cp *.log ~/Desktop"
nie potrzebuje zmiany w katalogu, ponieważ
cp /var/log/*.log ~/Desktop
zrobiłby to samo. Czy nie możesz zbliżyć się do swojego prawdziwego problemu? Ponieważ możemy również znać lepsze rozwiązanie tego problemu.
Skomplikowanym sposobem rozwiązania problemu, który jest daleki od elegancji rozwiązania Michaels, jest użycie funkcji find, która ma przełącznik „-execdir” do wykonania w katalogu, w którym znajduje się plik. Źle przystosowane do twojego przykładu:
find /var/log -maxdepth 1 -type f -name "*.log" -execdir echo cp {} ~/Desktop ";"
Może jest to przydatne dla twojego prawdziwego problemu. -okdir zamiast -execdir poprosi o potwierdzenie każdego wywołania.
-okdir i -execdir mogą wymagać zainstalowania gnu-find, zwykle używanego w Linuksie.
Jak o ./your/path/command.sh
?
execindirectory -d /var/log "cp *.log ~/Desktop"
.
echo "#!/bin/bash; cd $1; exec $2" > /usr/local/bin/execindirectory; chmod +x /usr/local/bin/execindirectory
. Może wymagać trochę więcej wysiłku, jeśli chcesz, aby rzeczywiście obsługiwał „tagi” opcji, takie jak-d
i inne.