Alias ​​vers CD dans un répertoire et appel d'une commande

21

J'ai un .bash_profileet en ce que j'ai un ensemble d'alias. Ces alias n'exécutent actuellement qu'une seule commande et c'était assez facile. Je voudrais cependant faire deux choses avec un nouvel alias que j'essaie de créer.

  1. CD dans un répertoire
  2. Exécutez une commande à partir de ce répertoire
user232103
la source

Réponses:

26

Pour exécuter une commande avec un répertoire de travail spécifique, on fait généralement

( cd directory && utility )

Les parenthèses autour du cd ... moyen signifient que la ou les commandes qui s'y trouvent s'exécutent en sous-shell. La modification du répertoire de travail dans un sous-shell fait en sorte que le répertoire de travail actuel du shell appelant ne soit pas modifié, c'est-à-dire qu'après avoir appelé cette commande, vous serez toujours dans le même répertoire que celui où vous avez commencé.

Exemple:

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

Cela ne peut pas être transformé en un alias générique car un alias ne peut prendre aucun argument.

Pour un répertoire et un utilitaire spécifiques , on pourrait faire

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

mais pour le cas général, vous devrez utiliser une fonction shell:

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

ou

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

Le remplacement des accolades par des parenthèses autour du corps de la fonction fait exécuter la fonction dans son propre sous-shell.

Ce serait utilisé comme

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

qui exécuterait le script script.shsitué dans le répertoire $HOME/somedir, avec $HOME/somedircomme répertoire de travail, ou

$ cdrun / ls -l

qui vous fournirait une liste de répertoires au "format long" du répertoire racine.

La fonction shell prend son premier argument et essaie de passer à ce répertoire. Si cela fonctionne, il décale le nom du répertoire des paramètres positionnels (la liste des arguments de la ligne de commande) et exécute la commande donnée par le reste des arguments. commandest une commande intégrée dans le shell qui exécute simplement ses arguments en tant que commande.


Tout cela est nécessaire si vous souhaitez exécuter une commande avec un répertoire de travail modifié . Si vous souhaitez simplement exécuter une commande située ailleurs, vous pouvez évidemment utiliser

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

mais courrais script.shsitué dans $HOME/somedirle courant répertoire que le répertoire de travail.

Une autre façon d'exécuter un script situé ailleurs sans modifier le répertoire de travail consiste à ajouter l'emplacement du script à votre PATHvariable d'environnement, par exemple

PATH="$PATH:$HOME/somedir"

Maintenant , script.shen $HOME/somedirsera en mesure d'être exécuté à partir n'importe où en utilisant simplement

$ script.sh

Encore une fois, cela ne modifie pas le répertoire de travail de la commande.

Kusalananda
la source
2
Excellente réponse complète. Je pensais juste que je mentionne que la définition de la fonction ne nécessite qu'une seule méthode de commandes regroupement et les parenthèses pour la sous - shell sont assez: cdrun () ( cd "$1" && shift && command "$@" ).
Anthony G - justice pour Monica
2
@AnthonyGeoghegan Ah, c'est vrai. J'utilise toujours { ... }pour la cohérence avec des fonctions plus longues.
Kusalananda
Cette Q&R semble parler de ma situation et peut être une amélioration de l'utilisation d'un environnement pushdet popd(également > /dev/nullsi vous essayez également d'éviter les messages de sortie), tout en gardant le contexte propre!
Pysis
1
@Pysis Oui, (cd dir && thing)est également beaucoup plus portable que l'utilisation de pushdet popd.
Kusalananda
@Kusalananda Vraiment? Je les ai fait travailler pour au moins plusieurs systèmes.
Pysis
4
alias <name-of-the-alias>='cd <the-directory> && <command>'

Donc, si vous voulez changer de répertoire (cd) dans le dossier /var/log/puis lister (ls) ses fichiers, vous pouvez ajouter dans votre .bash_profilefichier ce qui suit:

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

J'utilise cette fonction pour exécuter une seule commande dans un répertoire différent:

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

Une limitation de cette fonction est que les caractères génériques sont terminés par rapport au répertoire d'origine, et non par rapport au répertoire où la commande s'exécute. Il est possible de faire mieux en zsh .

Cette fonction agit comme l'ordinaire cdsi elle est appelée avec un seul argument, vous pouvez donc l'appeler cd. (Cette fonction ne prend en charge aucune option, mais les options à cdsont rarement utilisées.)

Gilles 'SO- arrête d'être méchant'
la source
-1

Séparez les commandes par un point-virgule, par exemple:

alias do_something='cd /tmp; ls'
John Elliot V
la source
8
En cas d' cdéchec, vous obtiendrez la liste des répertoires du mauvais répertoire. Il vaut mieux utiliser &&plutôt ;qu'ici.
Kusalananda
@Kusalananda a raison. Vous pouvez trouver plus dans cette réponse
nikolas