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

11

Comment réutiliser la apt uppartie des commandes apt updateet apt upgradepour exécuter les deux commandes en séquence sur une seule ligne sans alias.

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

e200
la source
Quel serait réellement le but d'y parvenir? Pourquoi cela peut-il être intéressant / pertinent?
vanadium
25
@vanadium nous sommes des utilisateurs de linux, essayer des choses inutiles nous permet d'apprendre des techniques qui peuvent être appliquées plus tard à des choses plus complexes, si aucun de nous ne l'a fait, soyons honnêtes, aucun d'entre nous ne serait là
Darren H
1
@DarrenH C'est ce que je pensais en effet :-)
vanadium

Réponses:

19

La manière simple (et plus efficace) est via une boucle for (sur une ligne, mais ici, elle est affichée sur plusieurs lignes pour plus de clarté):

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

La façon intelligente consiste à créer un alias ~/.bashrcpour ces deux commandes et à ne plus jamais le retaper:

alias upgrade=' sudo apt update && sudo apt upgrade'

La façon la plus élaborée est de le faire:

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

Vous voyez ce qui se passe? Nous construisons une chaîne de texte valide à exécuter par shell. Il ne vous reste plus qu'à utiliser à la evalplace de echo. Mais elle evaln'est généralement pas recommandée 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 de la pipe et de plusieurs commandes echo, deux apt, sudoet shdonc beaucoup de fourches):

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

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

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

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

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

L'utilisation setest une technique très courante que je vois chez les professionnels qui travaillent beaucoup avec des coques, et pour une bonne raison - c'est très portable et fonctionnera /bin/shlà où vous n'avez pas de baies ou d' {a,b,c}expansion. Donc, la manière portable POSIX serait set update upgrade ; for i; do echo apt $i ;done. De plus, cela devrait être efficace.


Ou nous pouvons emprunter la whileboucle:

$ 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 l'exécution de la commande ait lieu

Sergiy Kolodyazhnyy
la source
7
Faites simplement la boucle for sur une seule ligne. for i in {date,grade}; do sudo apt up${i}; done
Videonauth
3
Si vous préférez conserver vos fichiers bien rangés, vous pouvez également y insérer des alias ~/.bash_aliases. Ce fichier doit provenir automatiquement de ~/.bashrc.
francescop21
2
J'ai mis à jour ma réponse avec peut-être ce que vous voulez. C'est une doublure, mais je ne pense pas que cela facilite la tâche. Franchement, cela ne sert à rien de faire cela lorsque vous voulez exécuter deux commandes (oui, c'est deux aptcommandes) avec des arguments différents (mise à jour et mise à niveau), donc je dirai toujours que la boucle est la voie à suivre
Sergiy Kolodyazhnyy
1
Pas besoin d'extension de chaîne pour l'en-tête de boucle, il suffit de nommer les itérations:for i in date grade; do
rexkogitans
5
Un tel alias doit évidemment être nommé upgrate.
pipe
14

Vous pouvez également utiliser l'expansion de l'historique bash 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 actuelle
  • :s/date/gradeest un modificateur qui se substitue dateàgrade
muru
la source
6
Vous pouvez même enregistrer 2 autres personnages en utilisant à la !#:s/dat/gradplace
Dan
9

Une autre option simple utilisant xargsau 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 de shell tout comme Sergiy parce que ces méthodes «simples» ne sont pas assez simples pour être réellement utiles.

Melebius
la source
1
Très agréable. La variation sur le thème pourrait être printf "%s\n" {date,grade} | xargs -I% -n1 echo apt up%bien que ce soit un peu plus long
Sergiy Kolodyazhnyy
printf '%s'est généralement une bonne pratique car vous ne pouvez pas y échapper, par exemple avec --helpou -e.
yyny
@YoYoYonnY Oui. Ce printf '%s\0'serait peut -être encore mieux, xargsa un drapeau pour gérer les
arguments
2

Créez une fonction comme celle-ci:

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

Ensuite, vous pouvez courir 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 que quelque chose comme ça est probablement plus utile:

alias apt-up='apt update && apt upgrade'
Matthew Read
la source
0

La réponse de @ muru m'a amené à lire sur l'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 string1par string2.

guntbert
la source
-2

Je réutilise la apt-get uppartie de la commande en utilisant la séquence de touches suivante:

Up ArrowBackspaceBackspaceBackspaceBackspace

jdgregson
la source