Gunakan kembali bagian `apt up` dari perintah` apt update` dan `apt upgrade` untuk mengeksekusi keduanya secara berurutan hanya dalam satu baris

11

Cara menggunakan kembali apt upbagian dari apt updatedan apt upgradeperintah untuk menjalankan kedua perintah secara berurutan hanya dalam satu baris tanpa alias.

Sesuatu seperti: apt up{date,grade}.

e200
sumber
Apa yang sebenarnya menjadi tujuan untuk mencapai ini? Mengapa ini menarik / relevan?
vanadium
25
@vanadium, kami adalah pengguna linux, mencoba hal-hal yang tidak berguna memungkinkan kami mempelajari teknik yang dapat diterapkan kemudian untuk hal-hal yang lebih kompleks, jika tidak ada di antara kita yang pernah melakukannya, mari kita jujur, tidak ada dari kita yang ada di sini
Darren H
1
@ DarrenH Itulah yang saya pikir memang :-)
vanadium

Jawaban:

19

Cara sederhana (dan lebih efisien) adalah melalui for loop (pada satu baris tetapi di sini ditunjukkan dalam beberapa baris untuk kejelasan):

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

Cara cerdas adalah membuat alias di ~/.bashrcuntuk dua perintah ini dan lupa mengetik ulang lagi:

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

Cara rumit untuk melakukan ini:

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

Lihat apa yang terjadi? Kami sedang membangun string teks yang valid untuk dijalankan oleh shell. Sekarang yang perlu Anda lakukan adalah menggunakan evalalih-alih echo. Tetapi evalumumnya tidak direkomendasikan dalam skrip shell dan perintah ini jauh lebih berbelit-belit dan tidak portabel daripada for loop. Variasi pada tema tanpa eval (dan terpendek sejauh ini, tetapi tidak efisien karena pipa dan banyak perintah echo, dua apt, sudodan shbegitu banyak forking):

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

Kita juga dapat menggunakan setuntuk mengubah urutan yang diinginkan menjadi parameter posisi dan jalankan aptdengan $1dan $2args:

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

Atau gunakan lagi untuk loop, karena default untuk memproses parameter posisi jika Anda tidak menentukan urutan dalam for variable (sequence)

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

Menggunakan setadalah teknik yang sangat umum yang saya lihat di kalangan profesional yang sering bekerja dengan kerang, dan untuk alasan yang baik - ini sangat portabel dan akan bekerja di /bin/shmana Anda tidak memiliki array atau {a,b,c}ekspansi. Jadi cara POSIX-ly portabel akan set update upgrade ; for i; do echo apt $i ;done. Selain itu, ini harus efisien.


Atau kita bisa menuju whilerute loop:

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

Tentu saja ingat untuk menjalankannya tanpa echoeksekusi perintah yang sebenarnya terjadi

Sergiy Kolodyazhnyy
sumber
7
Lakukan saja for loop dalam satu baris. for i in {date,grade}; do sudo apt up${i}; done
Videonauth
3
Jika Anda lebih suka menjaga file Anda tetap rapi dan rapi, Anda juga bisa memasukkan alias ~/.bash_aliases. File ini harus diambil secara otomatis oleh ~/.bashrc.
francescop21
2
Saya telah memperbarui jawaban saya dengan apa yang Anda inginkan. Ini adalah one-liner, tetapi saya tidak berpikir jika itu membuatnya lebih mudah. Terus terang, tidak ada gunanya melakukan ini ketika Anda ingin menjalankan dua perintah (ya, itu adalah dua aptperintah) dengan argumen yang berbeda (perbarui dan tingkatkan), jadi saya masih akan mengatakan untuk loop adalah cara untuk pergi
Sergiy Kolodyazhnyy
1
Tidak perlu ekspansi string untuk header loop, cukup for i in date grade; do
beri
5
Alias ​​semacam itu jelas harus dinamai upgrate.
pipa
14

Anda juga dapat menggunakan ekspansi bash history untuk mendapatkan bagian dari baris perintah saat ini dan memodifikasinya:

$ apt update; !#:s/date/grade
apt update; apt upgrade;
Reading package lists... Done
...
  • !# adalah baris saat ini
  • :s/date/gradeadalah pengubah yang pengganti datedengangrade
muru
sumber
6
Anda bahkan dapat menyimpan 2 karakter lainnya menggunakan !#:s/dat/gradbukannya
Dan
9

Pilihan sederhana lain menggunakan xargsbukan for:

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

Uji:

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

Namun, saya lebih suka shell alias seperti Sergiy karena cara-cara "sederhana" ini tidak cukup sederhana untuk benar-benar bermanfaat.

Melebius
sumber
1
Sangat bagus. Variasi pada tema mungkin printf "%s\n" {date,grade} | xargs -I% -n1 echo apt up%meskipun ini sedikit lebih lama
Sergiy Kolodyazhnyy
printf '%s'umumnya merupakan praktik yang baik karena Anda tidak dapat menghindarinya, misalnya dengan --helpatau -e.
yyny
@YoYoYonnY Ya. Mungkin printf '%s\0'akan lebih baik, xargsmemiliki bendera untuk menangani argumen yang dihentikan nol
Sergiy Kolodyazhnyy
2

Buat fungsi seperti ini:

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

Maka Anda bisa lari repeat 'apt up' {date,grade}. Ini memiliki manfaat menjadi dapat digunakan kembali untuk perintah yang sama sekali berbeda, meskipun Anda tidak perlu mengetik untuk yang ini.

Saya pasti setuju dengan beberapa jawaban lain bahwa sesuatu seperti ini mungkin lebih bermanfaat:

alias apt-up='apt update && apt upgrade'
Matius Baca
sumber
0

Jawaban @ muru membuat saya membaca tentang ekspansi sejarah dan saya menemukan varian lain

 $ sudo apt update
 $ ^dat^grad^

^string1^string2^setara dengan !!:s/string1/string2/, yang mengambil perintah terakhir dan diganti string1dengan string2.

Guntbert
sumber
-2

Saya menolak kembali apt-get upbagian dari perintah menggunakan urutan tombol berikut:

Up ArrowBackspaceBackspaceBackspaceBackspace

jdgregson
sumber