Użyj ponownie części „apt up” komend „apt update” i „apt upgrade”, aby wykonać obie sekwencje w jednym wierszu

11

Jak ponownie wykorzystać apt upczęść poleceń apt updatei apt upgradedo wykonania obu poleceń w jednym wierszu bez aliasu.

Coś jak: apt up{date,grade}.

e200
źródło
Jaki byłby cel tego osiągnięcia? Dlaczego może to być interesujące / istotne?
wanad
25
@vanadium jesteśmy użytkownikami Linuksa, próbowanie bezsensownych rzeczy pozwala nam nauczyć się technik, które można później zastosować do bardziej złożonych rzeczy, gdyby nikt z nas tego nie zrobił, to bądźmy szczerzy, że nie byłoby nas tutaj
Darren H
1
@DarrenH Tak właśnie myślałem :-)
wanad

Odpowiedzi:

19

Prostym sposobem (i bardziej wydajnym) jest przejście przez pętlę for (w jednej linii, ale tutaj jest pokazane w wielu liniach dla przejrzystości):

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

Sprytnym sposobem jest utworzenie aliasu ~/.bashrcdla tych dwóch poleceń i zapomnienie o ponownym wpisywaniu go ponownie:

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

Skomplikowany sposób to zrobić:

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

Zobacz co się dzieje? Budujemy prawidłowy ciąg tekstu do uruchomienia przez powłokę. Teraz wystarczy użyć evalzamiast echo. Ale evalgeneralnie nie jest zalecane w skryptach powłoki, a to polecenie jest znacznie bardziej skomplikowane i nieprzenośne niż pętla for. Wariacja na temat bez eval (i najkrótsza tak daleko, ale nie efektywne ze względu na rury i wielu poleceń echo, dwa apt, sudoi shtak wiele rozwidlone):

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

Możemy również użyć, setaby zmienić żądaną sekwencję w parametry pozycyjne i po prostu wykonać za aptpomocą $1i $2args:

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

Lub użyj ponownie pętli for, ponieważ domyślnie przetwarza parametry pozycyjne, jeśli nie określisz sekwencji w for variable (sequence)

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

Używanie setjest bardzo popularną techniką, którą widzę wśród profesjonalistów, którzy często pracują z powłokami, i nie bez powodu - jest to bardzo przenośne i będzie działać /bin/shtam, gdzie nie masz tablic ani {a,b,c}rozszerzeń. Tak więc POSIX-ly przenośny sposób byłby set update upgrade ; for i; do echo apt $i ;done. Dodatkowo powinno to być skuteczne.


Lub możemy przejść whiletrasę pętli:

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

Oczywiście pamiętaj, aby uruchomić go bez echorzeczywistego wykonania polecenia

Sergiy Kolodyazhnyy
źródło
7
Po prostu wykonaj pętlę for w jednej linii. for i in {date,grade}; do sudo apt up${i}; done
Videonauth,
3
Jeśli wolisz, aby twoje pliki były ładne i uporządkowane, możesz także wstawiać aliasy ~/.bash_aliases. Ten plik powinien zostać automatycznie pobrany przez ~/.bashrc.
francescop21,
2
Zaktualizowałem moją odpowiedź, być może, czego chcesz. Jest to jedna linijka, ale nie sądzę, czy to ułatwia. Szczerze mówiąc, nie ma sensu tego robić, jeśli chcesz uruchomić dwa polecenia (tak, to są dwa aptpolecenia) z różnymi argumentami (aktualizacja i aktualizacja), więc nadal powiem, że droga do pętli jest
lepsza
1
Nie ma potrzeby rozszerzania łańcucha w nagłówku pętli, wystarczy nazwać iteracje:for i in date grade; do
rexkogitans
5
Taki alias należy oczywiście nazwać upgrate.
rura
14

Możesz także użyć rozszerzenia historii bash, aby uzyskać części bieżącego wiersza poleceń i zmodyfikować go:

$ apt update; !#:s/date/grade
apt update; apt upgrade;
Reading package lists... Done
...
  • !# jest bieżącą linią
  • :s/date/gradejest modyfikatorem, który zastępuje datesięgrade
muru
źródło
6
Możesz nawet zapisać 2 kolejne postacie, używając !#:s/dat/gradzamiast tego
Dan
9

Kolejna prosta opcja xargszamiast zamiast for:

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

Test:

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

Wolałbym jednak alias powłoki, tak jak Sergiy, ponieważ te „proste” sposoby nie są wystarczająco proste, aby były przydatne.

Melebius
źródło
1
Bardzo dobrze. Wariacje na temat mogą być printf "%s\n" {date,grade} | xargs -I% -n1 echo apt up%nieco dłuższe
Sergiy Kolodyazhnyy
printf '%s'jest ogólnie dobrą praktyką, ponieważ nie można uciec, np. przy pomocy --helplub -e.
rr
@YoYoYonnY Tak. Może printf '%s\0'byłoby jeszcze lepiej, xargsma flagę do obsługi argumentów zakończonych
zerami
2

Utwórz taką funkcję:

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

Potem możesz biec repeat 'apt up' {date,grade}. Ma to tę zaletę, że można go używać do zupełnie różnych poleceń, chociaż nie oszczędza to pisania na klawiaturze.

Z pewnością zgodziłbym się z niektórymi innymi odpowiedziami, że coś takiego jest prawdopodobnie bardziej przydatne:

alias apt-up='apt update && apt upgrade'
Matthew Read
źródło
0

Odpowiedź @ muru doprowadziła mnie do przeczytania o rozszerzeniu historii i znalazłem inny wariant

 $ sudo apt update
 $ ^dat^grad^

^string1^string2^jest równoważne z !!:s/string1/string2/, które przyjmuje ostatnie polecenie i zastępuje string1je string2.

guntbert
źródło
-2

Ponownie wykorzystuję apt-get upczęść polecenia, używając następującej sekwencji klawiszy:

Up ArrowBackspaceBackspaceBackspaceBackspace

jdgregson
źródło