substitution paresseuse bashrc

10

Comment obtenir des ~/.bashrcalias pour évaluer les $()substitutions au moment de l'exécution , plutôt qu'au moment où ~ / .bashrc est exécuté (lors de l'ouverture d'un terminal)?

J'exécute cette commande assez souvent pour que je souhaite lui ajouter un alias:

svn diff -r $(svn info | grep ^Revision | awk {'print $2'}):HEAD $(svn info | grep ^URL | awk {'print $2'}) | colordiff

Cependant, lorsque je l'ajoute à ~/.bashrcun alias, je vois que les évaluations sont codées en dur aux valeurs qu'elles avaient au moment où j'ai ouvert le terminal:

$ alias
alias svnbranch='svn diff -r 178184:HEAD svn+ssh://branches/t4252 | colordiff'

Si j'ouvre un terminal, ~j'obtiens des erreurs:

svn: E155007: '/home/dotancohen' is not a working copy
svn: E155007: '/home/dotancohen' is not a working copy
svn: E155007: '/home/dotancohen' is not a working copy
svn: E155007: '/home/dotancohen' is not a working copy
$ alias
alias svnbranch='svn diff -r :HEAD  | colordiff'
$

J'ai essayé ces deux variantes de l'alias dans ~/.bashrc, elles ont toutes les deux le même effet (comme je m'y attendais):

alias svnbranch="svn diff -r $(svn info | grep ^Revision | awk {'print $2'}):HEAD $(svn info | grep ^URL | awk {'print $2'}) | colordiff"
alias svnbranch="svn diff -r `svn info | grep ^Revision | awk {'print $2'}`:HEAD `svn info | grep ^URL | awk {'print $2'}` | colordiff"

Comment obtenir des ~/.bashrcalias pour évaluer les $()substitutions au moment de l'exécution ?

De plus, comment rechercher cette situation dans Google? J'ai essayé de google sur "substitution bashrc", "substitution bashrc paresseux", et d'autres phrases clés, mais je n'ai rien trouvé pour ce que je pense être un problème assez courant pour trouver des informations.

dotancohen
la source
2
Pourquoi faut-il que ce soit un alias? Déplacez-le dans un script shell et terminez-en. La plupart des systèmes de type * ix sont mis $HOME/bindans le PATHsi vous avez un tel répertoire de nos jours.
Warren Young
@WarrenYoung: Vous avez raison, cette instance particulière pourrait être un script. Cependant, je voudrais toujours connaître la réponse car je préfère les alias pour d'autres choses et je vais certainement rencontrer cela. Je pourrais généraliser votre question en "pourquoi Bash supporte-t-il les alias alors que quelque chose pourrait être un script."
dotancohen
Pourquoi le downvote? Comment pourrais-je améliorer la question? J'ai fourni des exemples, des tentatives infructueuses et même les phrases clés sur lesquelles j'ai essayé de google.
dotancohen
@dotancohen: Je pense que vous devriez demander cela séparément. Je donne ici une réponse partielle: alias cdp="cd ~/projects". Impossible de le faire dans un script shell.
Warren Young

Réponses:

11

Utilisez des guillemets simples pour supprimer le traitement des caractères spéciaux. Vous pouvez également annuler le $ s.

Pour une commande complexe, il vaut probablement mieux utiliser une fonction dans tous les cas, qui ne nécessite aucun échappement et est plus facile à lire et à modifier:

svnbranch() {
    svn diff -r $(svn info | grep ^Revision | awk {'print $2'}):HEAD $(svn info | grep ^URL | awk {'print $2'}) | colordiff
}

Vous pouvez définir une fonction partout où vous pouvez définir un alias.

Michael Homer
la source
2
awka un espace de motif ainsi awk '/^Revision/{ print ...}' donc pas besoin de grep dans ce cas.
Valentin Bajrami