Làm thế nào để sử dụng lại apt up
một phần của các lệnh apt update
và apt 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}
.
Làm thế nào để sử dụng lại apt up
một phần của các lệnh apt update
và apt 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}
.
Câu trả lời:
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 ~/.bashrc
cho 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 eval
thay vì echo
. Nhưng eval
thườ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
, sudo
và sh
rấ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 apt
với $1
và $2
args:
$ 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 set
là 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/sh
nơ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 while
tuyế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 echo
thực hiện lệnh thực tế
for i in {date,grade}; do sudo apt up${i}; done
~/.bash_aliases
. Tập tin này sẽ được tự động nguồn bởi ~/.bashrc
.
apt
lệ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
for i in date grade; do
upgrate
.
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/grade
là một sửa đổi thay thế date
bằnggrade
!#:s/dat/grad
thay vào đó
Một tùy chọn đơn giản khác sử dụng xargs
thay 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.
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
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 --help
hoặc -e
.
printf '%s\0'
sẽ tốt hơn nữa, xargs
có một lá cờ để xử lý các đối số bị chấm dứt null
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'
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ế string1
bằng string2
.