Reutilice la parte `apt up` de los comandos` apt update` y `apt upgrade` para ejecutar ambos en secuencia en una sola línea

11

Cómo reutilizar la apt upparte de los comandos apt updatey apt upgradepara ejecutar ambos comandos en secuencia en una sola línea sin un alias.

Algo así como: apt up{date,grade}.

e200
fuente
¿Cuál sería en realidad el objetivo de lograr esto? ¿Por qué puede ser esto interesante / relevante?
vanadio
25
@vanadium somos usuarios de Linux, probar cosas sin sentido nos permite aprender técnicas que luego se pueden aplicar a cosas más complejas, si ninguno de nosotros lo hiciera, seamos honestos, ninguno de nosotros estaría aquí
Darren H
1
@DarrenH Eso es lo que realmente pensé :-)
vanadio

Respuestas:

19

La forma simple (y más eficiente) es a través del bucle for (en una línea, pero aquí se muestra en varias líneas para mayor claridad):

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

La forma inteligente es crear un alias ~/.bashrcpara estos dos comandos y olvidarse de volver a escribirlo de nuevo:

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

La forma elaborada es hacer esto:

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

¿Ves lo que está pasando? Estamos creando una cadena de texto válida para que Shell la ejecute. Ahora todo lo que necesita hacer es usar en evallugar de echo. Pero evalgeneralmente no se recomienda en las secuencias de comandos de shell y este comando es mucho más complicado y no portátil que el bucle for. Variación sobre el tema sin evaluación (y la más corta hasta ahora, pero no eficiente debido a la tubería y múltiples comandos echo, dos apt, sudoy shmucho bifurcación):

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

También podemos usar setpara convertir la secuencia deseada en parámetros posicionales y simplemente ejecutar aptcon $1y $2args:

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

O, alternativamente, use for loop nuevamente, ya que el valor predeterminado es procesar parámetros posicionales si no especifica una secuencia en el for variable (sequence)

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

El uso setes una técnica muy común que veo entre los profesionales que trabajan mucho con los shells, y por una buena razón: es muy portátil y funcionará /bin/shdonde no hay arrays ni {a,b,c}expansión. Así sería POSIX-ly portátil set update upgrade ; for i; do echo apt $i ;done. Además, esto debería ser eficiente.


O podemos ir a la whileruta del bucle:

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

Por supuesto, recuerde ejecutarlo sin echoque tenga lugar la ejecución real del comando

Sergiy Kolodyazhnyy
fuente
77
Simplemente haga el bucle for en una línea. for i in {date,grade}; do sudo apt up${i}; done
Videonauth
3
Si prefiere mantener sus archivos limpios y ordenados, también puede poner alias ~/.bash_aliases. Este archivo debe ser obtenido automáticamente por ~/.bashrc.
francescop21
2
He actualizado mi respuesta con quizás lo que quieres. Es de una sola línea, pero no creo que lo haga más fácil. Francamente, no tiene sentido hacer esto cuando quieres ejecutar dos comandos (sí, son dos aptcomandos) con diferentes argumentos (actualizar y actualizar), así que todavía diré que el bucle es el camino a seguir
Sergiy Kolodyazhnyy
1
No es necesario expandir la cadena para el encabezado del bucle, solo nombra las iteraciones:for i in date grade; do
rexkogitans
55
Tal alias obviamente debe ser nombrado upgrate.
tubería
14

También puede usar la expansión del historial de bash para obtener partes de la línea de comando actual y modificarla:

$ apt update; !#:s/date/grade
apt update; apt upgrade;
Reading package lists... Done
...
  • !# es la línea actual
  • :s/date/gradees un modificador que sustituye datecongrade
muru
fuente
66
Incluso puede guardar más de 2 caracteres utilizando !#:s/dat/graden su lugar
Dan
9

Otra opción simple usando en xargslugar de for:

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

Prueba:

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

Sin embargo, preferiría un alias de shell como Sergiy porque estas formas "simples" no son lo suficientemente simples como para ser realmente útiles.

Melebio
fuente
1
Muy agradable. La variación sobre el tema podría ser printf "%s\n" {date,grade} | xargs -I% -n1 echo apt up%aunque esto sea un poco más largo
Sergiy Kolodyazhnyy
printf '%s'generalmente es una buena práctica ya que no puede escapar de ella, por ejemplo, con --helpo -e.
yyny
@YoYoYonnY Sí. Tal vez printf '%s\0'sería aún mejor, xargstiene una bandera para manejar args terminados nulos
Sergiy Kolodyazhnyy
2

Crea una función como esta:

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

Entonces puedes correr repeat 'apt up' {date,grade}. Esto tiene la ventaja de ser reutilizable para comandos totalmente diferentes, aunque no le ahorra ningún tipo de escritura para este.

Ciertamente estoy de acuerdo con algunas de las otras respuestas de que algo como esto probablemente sea más útil:

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

La respuesta de @ muru me llevó a leer sobre la expansión de la historia y encontré otra variante

 $ sudo apt update
 $ ^dat^grad^

^string1^string2^es equivalente a !!:s/string1/string2/, que toma el último comando y lo reemplaza string1con string2.

Guntbert
fuente
-2

Reutilizo la apt-get upparte del comando usando la siguiente secuencia de teclas:

Up ArrowBackspaceBackspaceBackspaceBackspace

jdgregson
fuente