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'
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:
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)
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.
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:
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:
Réponses:
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é):
La façon intelligente consiste à créer un alias
~/.bashrc
pour ces deux commandes et à ne plus jamais le retaper:La façon la plus élaborée est de le faire:
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
eval
place deecho
. Mais elleeval
n'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 commandesecho
, deuxapt
,sudo
etsh
donc beaucoup de fourches):Nous pouvons également utiliser
set
pour transformer la séquence souhaitée en paramètres positionnels et simplement exécuterapt
avec$1
et$2
args: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)
L'utilisation
set
est 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/sh
là où vous n'avez pas de baies ou d'{a,b,c}
expansion. Donc, la manière portable POSIX seraitset update upgrade ; for i; do echo apt $i ;done
. De plus, cela devrait être efficace.Ou nous pouvons emprunter la
while
boucle:Bien sûr, n'oubliez pas de l'exécuter sans
echo
pour que l'exécution de la commande ait lieula source
for i in {date,grade}; do sudo apt up${i}; done
~/.bash_aliases
. Ce fichier doit provenir automatiquement de~/.bashrc
.apt
commandes) avec des arguments différents (mise à jour et mise à niveau), donc je dirai toujours que la boucle est la voie à suivrefor i in date grade; do
upgrate
.Vous pouvez également utiliser l'expansion de l'historique bash pour obtenir des parties de la ligne de commande actuelle et la modifier:
!#
est la ligne actuelle:s/date/grade
est un modificateur qui se substituedate
àgrade
la source
!#:s/dat/grad
placeUne autre option simple utilisant
xargs
au lieu defor
:Tester:
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.
la source
printf "%s\n" {date,grade} | xargs -I% -n1 echo apt up%
bien que ce soit un peu plus longprintf '%s'
est généralement une bonne pratique car vous ne pouvez pas y échapper, par exemple avec--help
ou-e
.printf '%s\0'
serait peut -être encore mieux,xargs
a un drapeau pour gérer lesCréez une fonction comme celle-ci:
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:
la source
La réponse de @ muru m'a amené à lire sur l'expansion de l'histoire et j'ai trouvé une autre variante
^string1^string2^
est équivalent à!!:s/string1/string2/
, qui prend la dernière commande et remplacestring1
parstring2
.la source
Je réutilise la
apt-get up
partie de la commande en utilisant la séquence de touches suivante:Up ArrowBackspaceBackspaceBackspaceBackspace
la source