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'
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:
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.
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:
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:
Odpowiedzi:
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):
Sprytnym sposobem jest utworzenie aliasu
~/.bashrc
dla tych dwóch poleceń i zapomnienie o ponownym wpisywaniu go ponownie:Skomplikowany sposób to zrobić:
Zobacz co się dzieje? Budujemy prawidłowy ciąg tekstu do uruchomienia przez powłokę. Teraz wystarczy użyć
eval
zamiastecho
. Aleeval
generalnie 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
, dwaapt
,sudo
ish
tak wiele rozwidlone):Możemy również użyć,
set
aby zmienić żądaną sekwencję w parametry pozycyjne i po prostu wykonać zaapt
pomocą$1
i$2
args:Lub użyj ponownie pętli for, ponieważ domyślnie przetwarza parametry pozycyjne, jeśli nie określisz sekwencji w
for variable (sequence)
Używanie
set
jest 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/sh
tam, gdzie nie masz tablic ani{a,b,c}
rozszerzeń. Tak więc POSIX-ly przenośny sposób byłbyset update upgrade ; for i; do echo apt $i ;done
. Dodatkowo powinno to być skuteczne.Lub możemy przejść
while
trasę pętli:Oczywiście pamiętaj, aby uruchomić go bez
echo
rzeczywistego wykonania poleceniaźródło
for i in {date,grade}; do sudo apt up${i}; done
~/.bash_aliases
. Ten plik powinien zostać automatycznie pobrany przez~/.bashrc
.apt
polecenia) z różnymi argumentami (aktualizacja i aktualizacja), więc nadal powiem, że droga do pętli jestfor i in date grade; do
upgrate
.Możesz także użyć rozszerzenia historii bash, aby uzyskać części bieżącego wiersza poleceń i zmodyfikować go:
!#
jest bieżącą linią:s/date/grade
jest modyfikatorem, który zastępujedate
sięgrade
źródło
!#:s/dat/grad
zamiast tegoKolejna prosta opcja
xargs
zamiast zamiastfor
:Test:
Wolałbym jednak alias powłoki, tak jak Sergiy, ponieważ te „proste” sposoby nie są wystarczająco proste, aby były przydatne.
źródło
printf "%s\n" {date,grade} | xargs -I% -n1 echo apt up%
nieco dłuższeprintf '%s'
jest ogólnie dobrą praktyką, ponieważ nie można uciec, np. przy pomocy--help
lub-e
.printf '%s\0'
byłoby jeszcze lepiej,xargs
ma flagę do obsługi argumentów zakończonychUtwórz taką funkcję:
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:
źródło
Odpowiedź @ muru doprowadziła mnie do przeczytania o rozszerzeniu historii i znalazłem inny wariant
^string1^string2^
jest równoważne z!!:s/string1/string2/
, które przyjmuje ostatnie polecenie i zastępujestring1
jestring2
.źródło
Ponownie wykorzystuję
apt-get up
część polecenia, używając następującej sekwencji klawiszy:Up ArrowBackspaceBackspaceBackspaceBackspace
źródło