Alias ​​auf CD in einem Verzeichnis und einen Befehl aufrufen

21

Ich habe ein .bash_profileund darin habe ich eine Reihe von Aliasen. Diese Aliase führen im Moment nur einen einzigen Befehl aus und es war ziemlich einfach. Ich möchte jedoch zwei Dinge mit einem neuen Alias ​​tun, den ich zu erstellen versuche.

  1. CD in ein Verzeichnis
  2. Führen Sie einen Befehl aus diesem Verzeichnis aus
user232103
quelle

Antworten:

26

Um einen Befehl mit einem bestimmten Arbeitsverzeichnis auszuführen, ist dies normalerweise der Fall

( cd directory && utility )

Die Klammern um cd ...bedeuten, dass die darin enthaltenen Befehle in einer Subshell ausgeführt werden. Das Ändern des Arbeitsverzeichnisses in einer Subshell bewirkt, dass das aktuelle Arbeitsverzeichnis der aufrufenden Shell nicht geändert wird, dh nach dem Aufrufen dieses Befehls befinden Sie sich immer noch in dem Verzeichnis, in dem Sie gestartet haben.

Beispiel:

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

Dies kann nicht in einen generischen Alias ​​umgewandelt werden, da ein Alias ​​keine Argumente annehmen kann.

Für ein bestimmtes Verzeichnis und Dienstprogramm könnte man das tun

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

aber für den allgemeinen Fall müssten Sie eine Shell-Funktion verwenden:

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

oder

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

Durch Ersetzen der geschweiften Klammern durch Klammern um den Funktionskörper wird die Funktion in einer eigenen Subshell ausgeführt.

Dies würde als verwendet werden

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

welches das script.shim Verzeichnis befindliche Skript $HOME/somedirmit $HOME/somedirals Arbeitsverzeichnis ausführen würde , oder

$ cdrun / ls -l

Dies würde Ihnen eine Verzeichnisliste im "langen Format" des Stammverzeichnisses liefern.

Die Shell-Funktion verwendet ihr erstes Argument und versucht, in dieses Verzeichnis zu wechseln. Wenn das funktioniert, verschiebt es den Verzeichnisnamen von den Positionsparametern (der Befehlszeilenargumentliste) weg und führt den Befehl aus, der von den restlichen Argumenten gegeben wird. commandist ein in die Shell integrierter Befehl, der seine Argumente einfach als Befehl ausführt.


All dies ist erforderlich, wenn Sie einen Befehl mit einem geänderten Arbeitsverzeichnis ausführen möchten . Wenn Sie nur einen Befehl ausführen möchten, der sich an einer anderen Stelle befindet, können Sie natürlich verwenden

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

aber dies würde script.shsich in $HOME/somedirdem aktuellen Verzeichnis als Arbeitsverzeichnis.

Eine andere Möglichkeit, ein Skript auszuführen, das sich an einer anderen Stelle befindet, ohne das Arbeitsverzeichnis zu ändern, besteht darin, der PATHUmgebungsvariablen den Speicherort des Skripts hinzuzufügen , z

PATH="$PATH:$HOME/somedir"

Jetzt kann script.shin $HOME/somedirvon überall mit ausgeführt werden

$ script.sh

Auch hierdurch wird das Arbeitsverzeichnis für den Befehl nicht geändert.

Kusalananda
quelle
2
Hervorragende, umfassende Antwort. Ich dachte nur , dass ich erwähnen , dass die Definition der Funktion braucht nur eine Methode von Befehlen Gruppierung und die Klammern für die Subshell sind genug: cdrun () ( cd "$1" && shift && command "$@" ).
Anthony G - Gerechtigkeit für Monica
2
@AnthonyGeoghegan Ah, das stimmt. Ich benutze immer { ... }für die Konsistenz mit längeren Funktionen.
Kusalananda
Diese Fragen und Antworten scheinen von meiner Situation zu sprechen und sind möglicherweise eine Verbesserung bei der Verwendung einer Umgebung pushdund popd(auch > /dev/nullwenn Sie versuchen, die ausgegebenen Nachrichten ebenfalls zu vermeiden), während Sie gleichzeitig den Kontext sauber halten!
Pysis
1
@Pysis Ja, (cd dir && thing)ist auch viel portabler als die Verwendung von pushdund popd.
Kusalananda
@ Kusalananda Wirklich? Ich habe sie für mindestens mehrere Systeme arbeiten lassen.
Pysis
4
alias <name-of-the-alias>='cd <the-directory> && <command>'

Wenn Sie also das Verzeichnis (cd) in den Ordner ändern /var/log/und dann dessen Dateien auflisten möchten, können Sie .bash_profileFolgendes in Ihre Datei einfügen :

alias logs='cd /var/log/ && ls'
nikolas
quelle
1

Ich benutze diese Funktion, um einen einzelnen Befehl in einem anderen Verzeichnis auszuführen:

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

Eine Einschränkung dieser Funktion besteht darin, dass Platzhalter relativ zum ursprünglichen Verzeichnis und nicht relativ zum Verzeichnis, in dem der Befehl ausgeführt wird, angegeben werden. In zsh kann man es besser machen .

Diese Funktion verhält sich wie gewohnt cd wenn sie mit einem einzelnen Argument aufgerufen wird cd. Sie können sie also aufrufen . (Diese Funktion unterstützt keine Optionen, aber Optionen, cddie nur selten verwendet werden.)

Gilles 'SO - hör auf böse zu sein'
quelle
-1

Kommandos durch Semikolon trennen, zB:

alias do_something='cd /tmp; ls'
John Elliot V
quelle
8
Wenn das cdfehlschlägt, würden Sie die Verzeichnisliste des falschen Verzeichnisses erhalten. Es ist besser, &&anstatt ;hier zu verwenden.
Kusalananda
@ Kusalananda ist richtig. Sie können mehr in dieser Antwort finden
Nikolas