Reutilize a parte `apt up` dos comandos` apt update` e `apt upgrade` para executar ambos em sequência em apenas uma linha


11

Como reutilizar a apt upparte dos comandos apt updatee apt upgradepara executar os dois comandos em sequência em apenas uma linha sem um alias.

Algo como: apt up{date,grade}.


Qual seria realmente o objetivo de conseguir isso? Por que isso pode ser interessante / relevante?
vanádio

25
@vanadium somos usuários de Linux, tentando coisas inúteis nos permite aprender técnicas que podem ser aplicadas mais tarde para coisas mais complexas, se nenhum de nós nunca fez nenhum ser honesto que nos deixa de nós estaria aqui
Darren H

1
@DarrenH Isso é o que eu pensei na verdade :-)
vanádio

Respostas:


19

A maneira simples (e mais eficiente) é via loop for (em uma linha, mas aqui é mostrada em várias linhas para maior clareza):

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

A maneira inteligente é criar um alias ~/.bashrcpara esses dois comandos e esquecer de digitá-lo novamente:

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

A maneira elaborada é fazer isso:

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

Veja o que está acontecendo? Estamos construindo uma sequência de texto válida para ser executada pelo shell. Agora tudo que você precisa fazer é usar em evalvez de echo. Mas evalgeralmente não é recomendado em scripts de shell e esse comando é muito mais complicado e não portátil do que o loop for. Variação sobre o tema sem eval (e mais curto até agora, mas não é eficiente devido à tubulação e comandos múltiplas echo, dois apt, sudoe shassim que os lotes de bifurcação):

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

Também podemos usar setpara transformar a sequência desejada em parâmetros posicionais e apenas executar aptcom $1e $2args:

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

Ou use alternativamente o loop for novamente, pois o padrão é o processamento de parâmetros posicionais se você não especificar uma sequência no for variable (sequence)

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

O uso seté uma técnica muito comum que eu vejo entre profissionais que trabalham muito com conchas, e por uma boa razão - é muito portátil e funcionará /bin/shonde você não tem matrizes ou {a,b,c}expansão. Maneira POSIX-ly portátil seria set update upgrade ; for i; do echo apt $i ;done. Além disso, isso deve ser eficiente.


Ou podemos seguir a whilerota do loop:

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

É claro que lembre-se de executá-lo sem echoque a execução real do comando ocorra


7
Basta fazer o loop for em uma linha. for i in {date,grade}; do sudo apt up${i}; done
Videonauth 22/10/19

3
Se você prefere manter seus arquivos em ordem, também pode colocar aliases ~/.bash_aliases. Este arquivo deve ser gerado automaticamente por ~/.bashrc.
francescop21

2
Atualizei minha resposta com talvez o que você deseja. É uma frase única, mas acho que não facilita. Francamente, não faz sentido fazer isso quando você deseja executar dois comandos (sim, são dois aptcomandos) com argumentos diferentes (atualização e atualização), então ainda direi que o loop é o caminho a seguir
Sergiy Kolodyazhnyy

1
Não há necessidade de expansão de string no cabeçalho de loop, apenas nomeie as iterações:for i in date grade; do
rexkogitans

5
Obviamente, esse apelido deve ser nomeado upgrate.
pipe

14

Você também pode usar a expansão do histórico do bash para obter partes da linha de comando atual e modificá-la:

$ apt update; !#:s/date/grade
apt update; apt upgrade;
Reading package lists... Done
...
  • !# é a linha atual
  • :s/date/gradeé um modificador que substitui dateporgrade

6
Você pode até salvar mais 2 caracteres usando em !#:s/dat/gradvez disso
221 Dan Dan

9

Outra opção simples usando, em xargsvez de for:

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

Teste:

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

No entanto, eu preferiria um apelido de shell como Sergiy, porque essas maneiras "simples" não são simples o suficiente para serem realmente úteis.


1
Muito agradável. Variação sobre o tema pode ser printf "%s\n" {date,grade} | xargs -I% -n1 echo apt up%embora isso seja um pouco mais longo
Sergiy Kolodyazhnyy 22/10/1918

printf '%s'geralmente é uma boa prática, pois você não pode escapar dela, por exemplo, com --helpou -e.
yyny

@YoYoYonnY Sim. Talvez printf '%s\0'seria ainda melhor, xargstem uma bandeira para lidar com argumentos terminados nulos #
Sergiy Kolodyazhnyy 22/10

2

Crie uma função como esta:

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

Então você pode correr repeat 'apt up' {date,grade}. Isso tem o benefício de ser reutilizável para comandos totalmente diferentes, embora não esteja poupando a digitação deste.

Eu certamente concordaria com algumas das outras respostas de que algo como isso é provavelmente mais útil:

alias apt-up='apt update && apt upgrade'

0

A resposta de @ muru me levou a ler sobre a expansão do histórico e encontrei outra variante

 $ sudo apt update
 $ ^dat^grad^

^string1^string2^é equivalente a !!:s/string1/string2/, que pega o último comando e substitui string1por string2.


-2

Eu reuso a apt-get upparte do comando usando a seguinte sequência de teclas:

Up ArrowBackspaceBackspaceBackspaceBackspace

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.