Sử dụng lại phần `apt up` của các lệnh` apt update` và` apt Nâng cấp 'để thực thi cả hai theo thứ tự chỉ trong một dòng


11

Làm thế nào để sử dụng lại apt upmột phần của các lệnh apt updateapt upgradeđể thực thi cả hai lệnh theo thứ tự chỉ trong một dòng mà không có bí danh.

Một cái gì đó như : apt up{date,grade}.


Điều gì thực sự sẽ là mục tiêu để đạt được điều này? Tại sao điều này có thể thú vị / có liên quan?
vanadi

25
@vanadi chúng tôi là người dùng linux, thử những thứ vô nghĩa cho phép chúng tôi học các kỹ thuật có thể áp dụng sau này cho những thứ phức tạp hơn, nếu không ai trong chúng tôi từng làm điều đó, hãy thành thật mà không ai trong chúng tôi sẽ ở đây
Darren H

1
@DarrenH Đó là những gì tôi nghĩ thực sự :-)
vanadi

Câu trả lời:


19

Cách đơn giản (và hiệu quả hơn) là thông qua vòng lặp for (trên một dòng nhưng ở đây nó được hiển thị trong nhiều dòng cho rõ ràng):

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

Cách thông minh là tạo một bí danh ~/.bashrccho hai lệnh này và quên đi việc gõ lại nó một lần nữa:

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

Cách thức công phu là làm điều này:

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

Xem những gì đang xảy ra? Chúng tôi đang xây dựng một chuỗi văn bản hợp lệ để được chạy bằng shell. Bây giờ tất cả những gì bạn cần làm là sử dụng evalthay vì echo. Nhưng evalthường không được khuyến nghị trong shell scripting và lệnh này phức tạp hơn nhiều và không khả dụng hơn so với vòng lặp for. Sự thay đổi về chủ đề không có eval (và ngắn nhất cho đến nay, nhưng không hiệu quả do đường ống và nhiều lệnh echo, hai apt, sudoshrất nhiều forking):

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

Chúng ta cũng có thể sử dụng setđể biến chuỗi mong muốn thành các tham số vị trí và chỉ thực hiện aptvới $1$2args:

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

Hoặc sử dụng thay thế cho vòng lặp một lần nữa, vì nó mặc định xử lý các tham số vị trí nếu bạn không chỉ định một chuỗi trong for variable (sequence)

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

Sử dụng setlà một kỹ thuật rất phổ biến tôi thấy trong số các chuyên gia làm việc với shell rất nhiều và vì một lý do chính đáng - điều này rất dễ mang theo và sẽ hoạt động ở /bin/shnơi bạn không có mảng hoặc {a,b,c}mở rộng. Vì vậy, POSIX-ly cách di động sẽ được set update upgrade ; for i; do echo apt $i ;done. Ngoài ra, điều này sẽ được hiệu quả.


Hoặc chúng ta có thể đi theo whiletuyến đường vòng:

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

Tất nhiên hãy nhớ chạy nó mà không echothực hiện lệnh thực tế


7
Chỉ cần thực hiện vòng lặp for trong một dòng. for i in {date,grade}; do sudo apt up${i}; done
Videonauth

3
Nếu bạn muốn giữ cho các tập tin của bạn đẹp và gọn gàng, bạn cũng có thể đặt bí danh ~/.bash_aliases. Tập tin này sẽ được tự động nguồn bởi ~/.bashrc.
francescop21

2
Tôi đã cập nhật câu trả lời của tôi với có lẽ những gì bạn muốn. Nó là một lớp lót, nhưng tôi không nghĩ rằng nó làm cho nó dễ dàng hơn. Thành thật mà nói, không có lý do gì để làm điều này khi bạn muốn chạy hai lệnh (vâng, đó là hai aptlệnh) với các đối số khác nhau (cập nhật và nâng cấp), vì vậy tôi vẫn sẽ nói rằng vòng lặp là cách để đi
Sergiy Kolodyazhnyy

1
Không cần mở rộng chuỗi trong tiêu đề vòng lặp, chỉ cần đặt tên cho các lần lặp:for i in date grade; do
rexkogitans

5
Một bí danh như vậy rõ ràng nên được đặt tên upgrate.
ống

14

Bạn cũng có thể sử dụng mở rộng lịch sử bash để lấy các phần của dòng lệnh hiện tại và sửa đổi nó:

$ apt update; !#:s/date/grade
apt update; apt upgrade;
Reading package lists... Done
...
  • !# là dòng hiện tại
  • :s/date/gradelà một sửa đổi thay thế datebằnggrade

6
Bạn thậm chí có thể lưu thêm 2 ký tự bằng cách sử dụng !#:s/dat/gradthay vào đó
Dan

9

Một tùy chọn đơn giản khác sử dụng xargsthay vì for:

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

Kiểm tra:

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

Tuy nhiên, tôi thích một bí danh vỏ giống như Sergiy bởi vì những cách đơn giản này của Pháp không đủ đơn giản để thực sự hữu ích.


1
Rất đẹp. Sự thay đổi về chủ đề có thể là printf "%s\n" {date,grade} | xargs -I% -n1 echo apt up%mặc dù điều này dài hơn một chút
Sergiy Kolodyazhnyy

printf '%s'nói chung là thực hành tốt vì bạn không thể thoát khỏi nó, ví dụ như với --helphoặc -e.
yyny

@YoYoYonnY Có. Có lẽ printf '%s\0'sẽ tốt hơn nữa, xargscó một lá cờ để xử lý các đối số bị chấm dứt null
Sergiy Kolodyazhnyy

2

Tạo một chức năng như thế này:

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

Sau đó, bạn có thể chạy repeat 'apt up' {date,grade}. Điều này có lợi ích là có thể tái sử dụng cho các lệnh hoàn toàn khác nhau, mặc dù nó không giúp bạn tiết kiệm bất kỳ thao tác gõ nào cho lệnh này.

Tôi chắc chắn đồng ý với một số câu trả lời khác rằng một cái gì đó như thế này có lẽ hữu ích hơn:

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

0

Câu trả lời của @ muru khiến tôi phải đọc về mở rộng lịch sử và tôi đã tìm thấy một biến thể khác

 $ sudo apt update
 $ ^dat^grad^

^string1^string2^là tương đương với !!:s/string1/string2/, trong đó có lệnh cuối cùng và thay thế string1bằng string2.


-2

Tôi apt-get upsử dụng lại một phần của lệnh bằng chuỗi khóa sau:

Up ArrowBackspaceBackspaceBackspaceBackspace

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.