Alias ​​na CD w katalogu i wywołać polecenie


21

Mam .bash_profilei tym samym mam zestaw aliasów. Te pseudonimy w tej chwili wykonują tylko jedno polecenie i było to dość łatwe. Chciałbym jednak zrobić dwie rzeczy z nowym aliasem, który próbuję utworzyć.

  1. CD do katalogu
  2. Uruchom polecenie z tego katalogu

Odpowiedzi:


26

Zazwyczaj wykonuje się polecenie w określonym katalogu roboczym

( cd directory && utility )

Nawiasy wokół cd ...oznaczają, że zawarte w nich polecenia działają w podpowłoce. Zmiana katalogu roboczego w podpowłoce powoduje, że bieżący katalog roboczy powłoki wywołującej nie ulega zmianie, tj. Po wywołaniu tej komendy nadal będziesz znajdować się w tym samym katalogu, w którym zacząłeś.

Przykład:

( cd / && echo "$PWD" )  # will output "/"
echo "$PWD"              # will output whatever directory you were in at the start

Nie można tego zmienić w ogólny alias, ponieważ alias nie może przyjmować żadnych argumentów.

Dla konkretnego katalogu i narzędzia można to zrobić

alias cdrun='( cd "$HOME/somedir" && ./script.sh )'

ale w ogólnym przypadku trzeba użyć funkcji powłoki:

cdrun () {
    ( cd "$1" && shift && command "$@" )
}

lub

cdrun () (
    cd "$1" && shift && command "$@"
)

Zastąpienie nawiasów klamrowych nawiasami wokół ciała funkcji powoduje, że funkcja jest wykonywana we własnej podpowłoce.

Byłoby to wykorzystane jako

$ cdrun "$HOME/somedir" ./script.sh

który uruchomiłby skrypt script.shznajdujący się w katalogu $HOME/somedir, z $HOME/somedirjako katalog roboczy, lub

$ cdrun / ls -l

który zapewniłby ci katalog w „długim formacie” katalogu głównego.

Funkcja powłoki pobiera swój pierwszy argument i próbuje przejść do tego katalogu. Jeśli to zadziała, zmienia nazwę katalogu z parametrów pozycyjnych (lista argumentów wiersza poleceń) i wykonuje polecenie podane przez resztę argumentów. commandto wbudowane polecenie w powłoce, które po prostu wykonuje swoje argumenty jako polecenie.


Wszystko to jest potrzebne, jeśli chcesz wykonać polecenie ze zmienionym katalogiem roboczym . Jeśli chcesz po prostu wykonać polecenie znajdujące się gdzie indziej, możesz oczywiście użyć

alias thing='$HOME/somedir/script.sh'

ale to byłoby script.shw mieście $HOME/somedirz bieżącym katalogu jako katalogu roboczego.

Innym sposobem wykonania skryptu znajdującego się gdzie indziej bez zmiany katalogu roboczego jest dodanie lokalizacji skryptu do PATHzmiennej środowiskowej, np.

PATH="$PATH:$HOME/somedir"

Teraz script.shw $HOME/somedirbędą mogły być uruchamiane z dowolnego miejsca tylko przy użyciu

$ script.sh

Ponownie nie zmienia to katalogu roboczego polecenia.


2
Doskonała, kompleksowa odpowiedź. Po prostu myślałem, że wspomnieć, że tylko definicja funkcji potrzebuje jednej metody grupowania komend i nawiasy dla podpowłoce wystarczą: cdrun () ( cd "$1" && shift && command "$@" ).
Anthony G - sprawiedliwość dla Moniki

2
@AnthonyGeoghegan Ah, to prawda. Zawsze jednak używam { ... }dla zachowania spójności z dłuższymi funkcjami.
Kusalananda

Wydaje się, że te pytania i odpowiedzi mówią o mojej sytuacji i mogą być ulepszeniem w korzystaniu z otoczenia pushdi popd(także > /dev/nulljeśli starasz się unikać komunikatów wyjściowych), jednocześnie utrzymując czysty kontekst!
Pysis

1
@Pysis Tak, (cd dir && thing)jest również znacznie bardziej przenośny niż używanie pushdi popd.
Kusalananda

@Kusalananda Naprawdę? Mam ich pracujących dla co najmniej kilku systemów.
Pysis

4
alias <name-of-the-alias>='cd <the-directory> && <command>'

Tak więc, jeśli chcesz zmienić katalog (cd) na folder, /var/log/a następnie wyświetlić listę (ls) jego plików, możesz dołączyć do .bash_profilepliku:

alias logs='cd /var/log/ && ls'

1

Korzystam z tej funkcji, aby uruchomić pojedyncze polecenie w innym katalogu:

cd1 () {
  if [ $# -eq 1 ]; then
    command cd -- "$1"
  else
    ( command cd -- "$1" && shift && "$@" )
  fi
}

Ograniczeniem tej funkcji jest to, że symbole wieloznaczne są wypełniane względem oryginalnego katalogu, a nie względem katalogu, w którym uruchamiane jest polecenie. Można zrobić lepiej w Zsh .

Ta funkcja działa jak zwykła, cdjeśli jest wywoływana za pomocą jednego argumentu, więc możesz chcieć ją wywołać cd. (Ta funkcja nie obsługuje żadnych opcji, ale opcje cdsą rzadko używane).


-1

Oddziel polecenia średnikiem, np .:

alias do_something='cd /tmp; ls'

8
Jeśli się cdnie powiedzie, otrzymasz listę katalogów niewłaściwego katalogu. Lepiej używać &&zamiast ;tutaj.
Kusalananda

@Kusalananda ma rację. Możesz znaleźć więcej w tej odpowiedzi
Nikolas
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.