web-dev-qa-db-fra.com

Réutilisez la partie `apt up` des commandes` apt update` et `apt upgrade` pour les exécuter en séquence sur une seule ligne

Comment réutiliser la partie apt up des commandes apt update et apt upgrade pour exécuter les deux commandes en séquence sur une seule ligne sans alias.

Quelque chose comme: apt up{date,grade}.

11
e200

Le moyen le plus simple (et le plus efficace) est de passer par la boucle for (sur une seule ligne, mais ici, elle apparaît en plusieurs lignes pour plus de clarté):

for i in {date,grade}; do
     apt up${i}
done

La solution la plus intelligente consiste à créer un alias dans ~/.bashrc pour ces deux commandes et à ne plus le retaper:

alias upgrade=' Sudo apt update && Sudo apt upgrade'

La manière élaborée est de faire ceci:

$ echo Sudo" "apt" "up{"date","grade"}" && " :
Sudo apt update &&  Sudo apt upgrade &&  :

Voir ce qui se passe? Nous construisons une chaîne de texte valide qui sera exécutée par Shell. Maintenant, tout ce que vous avez à faire est d’utiliser evalau lieu de echoname__. Mais evaln'est généralement pas recommandé dans les scripts Shell et cette commande est beaucoup plus compliquée et non portable que la boucle for. Variation sur le thème sans eval (et la plus courte jusqu'à présent, mais pas efficace en raison du tube et de plusieurs commandes echoname __, deux aptname __, Sudoet shso Ainsi beaucoup de forking):

$ echo "apt "{update,upgrade}";"|Sudo sh

Nous pouvons également utiliser setpour transformer la séquence souhaitée en paramètres de position et simplement exécuter aptavec $1 et $2 args:

$ set {update,upgrade}; echo apt $1 && echo apt $2
apt update
apt upgrade

Ou bien utilisez à nouveau boucle for, car elle utilise par défaut le traitement des paramètres de position si vous ne spécifiez pas de séquence dans la fonction for variable (sequence).

$ set {update,upgrade} ; for i; do echo apt $i ;done
apt update
apt upgrade

Utiliser setest une technique très courante chez les professionnels qui travaillent beaucoup avec les shells, et cela pour une bonne raison: cette solution est très portable et fonctionnera dans /bin/sh où vous n’avez pas de tableaux ni d’extensions {a,b,c}. Donc, manière portable POSIX-ly serait set update upgrade ; for i; do echo apt $i ;done. De plus, cela devrait être efficace.


Ou nous pouvons choisir la route de boucle whilename__:

$ echo {date,$'\n',grade}|while read i;do echo apt up${i}; done 
apt update
apt upgrade

Bien sûr, n'oubliez pas de l'exécuter sans echopour que la commande soit exécutée

19

Vous pouvez également utiliser bash expansion de l'historique pour obtenir des parties de la ligne de commande actuelle et la modifier:

$ apt update; !#:s/date/grade
apt update; apt upgrade;
Reading package lists... Done
...
  • !# est la ligne en cours
  • :s/date/grade est un modificateur qui substitue date à grade
14
muru

Une autre option simple utilisant xargs au lieu de for:

echo up{dat,grad}e | xargs -n1 apt

Tester:

$ echo up{dat,grad}e | xargs -n1 echo apt
apt update
apt upgrade

Cependant, je préférerais un alias Shell tout comme Sergiy car ces méthodes "simples" ne sont pas assez simples pour être réellement utiles.

9
Melebius

Créez une fonction comme celle-ci:

repeat() { 
    for suffix in "${@:2}";
    do
        eval "$1""$suffix";
    done
}

Ensuite, vous pouvez exécuter repeat 'apt up' {date,grade}. Cela a l'avantage d'être réutilisable pour des commandes totalement différentes, bien que cela ne vous évite pas de taper pour celle-ci.

Je suis certainement d’accord avec certaines des autres réponses pour dire que quelque chose comme ceci est probablement plus utile:

alias apt-up='apt update && apt upgrade'
2
Matthew Read

La réponse de @ muru m'a amené à lire expansion de l'histoire et j'ai trouvé une autre variante

 $ Sudo apt update
 $ ^dat^grad^

^string1^string2^ est équivalent à !!:s/string1/string2/, qui prend la dernière commande et remplace string1 par string2.

0
guntbert