Tổng quan chi tiết về cách viết kịch bản cho Bash Shell
Tập lệnh Shell là một cách mạnh mẽ để tự động hóa các tác vụ mà bạn thường xuyên thực thi trên máy tính của mình.
Trong hướng dẫn này, tôi đưa ra một cái nhìn tổng quan sâu rộng về shell scripting và sẽ là tài liệu tham khảo cơ bản cho các hướng dẫn chuyên sâu và nâng cao hơn về cách tạo shell script thực tế.
Kiểm tra của tôigiới thiệu về Bashbài đăng.
Bash cung cấp cho bạn một tập hợp các lệnh kết hợp với nhau có thể được sử dụng để tạo các chương trình nhỏ, theo quy ước chúng ta gọi là script.
Lưu ý sự khác biệt. Chúng tôi không nói lập trình Bash mà chỉ nói kịch bản Bash, và chúng tôi không gọi tập lệnh Bash là “chương trình Bash”. Điều này là do bạn thường có thể đạt đến một mức độ phức tạp nhất định trước khi cảm thấy rằng các tập lệnh của bạn đã vượt quá tầm tay.
Nhưng các tập lệnh Bash rất tuyệt vì bạn không cần bất cứ thứ gì khác ngoài Bash để chạy chúng. Không có trình biên dịch, không có trình thông dịch, chỉ là trình bao của bạn.
Có rất nhiều thứ mà bạn sẽ bỏ lỡ từ các ngôn ngữ lập trình như Perl hoặc JavaScript hoặc Python.
Các biến không có phạm vi, chúng đều là toàn cục, không có thư viện chuẩn, chẳng hạn như bạn không có hệ thống mô-đun. Nhưng ưu điểm là khá lớn: bạn có thể rất dễ dàng gọi bất kỳ công cụ CLI nào giống như khi bạn ở trong shell và cách tiếp cận Unix với việc có nhiều lệnh tiện ích nhỏ thực sự làm cho kịch bản shell trở nên tỏa sáng. Thực hiện các yêu cầu mạng vớiwget
, xử lý văn bản bằng cách sử dụngawk
, và hơn thế nữa.
Shell scripting là một trong những công cụ mà bạn nên biết, ít nhất là biết cách đọc một chương trình khi bạn nhìn thấy nó và những tiện ích mà nó có thể mang lại cho công việc hàng ngày của bạn.
Hướng dẫn này hướng dẫn bạn lý thuyết và khái niệm về Bash scripting. Tôi sẽ đăng các bài hướng dẫn chi tiết hơn về các kỹ thuật cụ thể hoặc cách giải quyết các vấn đề cụ thể trong tương lai.
Khái niệm cơ bản
Các tập lệnh được lưu trữ trong các tệp. Bạn có thể đặt bất kỳ tên và phần mở rộng nào cho tập lệnh shell, điều đó không quan trọng. Điều quan trọng là nó phải bắt đầu bằng “shebang” ở dòng đầu tiên:
#!/bin/bash
và nó phải là một tệp thực thi.
Một tệp được đặt làm tệp thực thi bằng cách sử dụngchmod
, một lệnh tiện ích.
Bạn có thể sử dụng nó như thế này:
chmod u+x myscript
để làm chomyscript
tệp thực thi cho người dùng của bạn (Tôi không đi sâu vào lỗ hổng cấp quyền ở đây, nhưng tôi sẽ trình bày chúng sớm).
Bây giờ bạn có thể thực thi tập lệnh nếu bạn đang ở trong cùng một thư mục bằng cách gọi nó./myscript
hoặc sử dụng đường dẫn đầy đủ đến nó.
Trong khi học, tôi khuyến khích bạn - khi có thể - sử dụng sân chơi trực tuyếngiống cái này, nó giúp mọi thứ kiểm tra dễ dàng hơn.
Bình luận
Nhận xét là một trong những điều quan trọng nhất khi viết chương trình. Một dòng bắt đầu bằng#
biểu tượng là một nhận xét (ngoại trừ dòng shebang mà bạn đã thấy ở trên ở đây).
#!/bin/bash
# this is a comment
Một nhận xét cũng có thể bắt đầu ở cuối dòng:
#!/bin/bash
echo ok # this is a comment
Biến
Bạn có thể đặt các biến bằng cách sử dụng=
nhà điều hành:
name=value
Ví dụ:
ROOM_NUMBER=237
name=Flavio
nickname="Flavio"
Bạn có thể in một biến bằng cách sử dụngecho
lệnh tích hợp sẵn và viết trước một$
đến tên var:
echo $ROOM_NUMBER
echo $name
Các nhà khai thác
Bash triển khai một số toán tử số học thường được sử dụng trên các ngôn ngữ lập trình:
+
thêm vào-
trừ đi*
nhân/
chia%
modulo (phần còn lại của phép chia)**
lũy thừa
Bạn có thể so sánh các giá trị bằng cách sử dụng
<
<=
==
>=
>
Bạn cũng có thể sử dụng các toán tử so sánh sau:
-lt
thấp hơn-gt
lớn hơn-le
thấp hơn hoặc bằng-ge
lớn hơn hoặc bằng-eq
tương đương với-ne
không bằng
Theo cách này:
#!/bin/bash
age=23
minimum=18
if test $age -lt $minimum
then
echo "Not old enough"
fi
Toán tử logic:
&&
logic AND||
logic HOẶC
Các phím tắt này cho phép thực hiện một phép toán số học và sau đó là một phép gán:
+=
-=
*=
/=
%=
Có một số toán tử khác, nhưng đó là những toán tử phổ biến nhất.
In ra màn hình
Bạn có thể in bất cứ thứ gì ra màn hình bằng cách sử dụngecho
chỉ huy:
#!/bin/bash
echo "test"
echo test
echo testing something
Điều kiện logic
AND: đánh giá thành0
(không) nếu cả haicommand
vàanothercommand
thực hiện và trở lại0
. Trả về số không trong các lệnh shell có nghĩa là lệnh đã thành công. Thông báo lỗi được xác định bằng giá trị trả về khác 0.
command && anothercommand
HOẶC: đánh giá thành0
(không) nếu ít nhất một trong sốcommand
vàanothercommand
thực hiện và trở lại0
.
command || anothercommand
KHÔNG: đảo ngược giá trị trả về logic củacommand
:
! command
Cấu trúc điều khiển
Trong bạn có thể sử dụng một số cấu trúc điều khiển mà bạn có thể quen thuộc:
Câu lệnh if / else
Đơn giảnif
:
if condition
then
command
fi
if
sau đóelse
:
if condition
then
command
else
anothercommand
fi
Lồng nhauif
- sau đó -else
:
if condition
then
command
elif
anothercommand
else
yetanothercommand
fi
Bạn có thể giữelse
trên cùng một dòng bằng cách sử dụng dấu chấm phẩy:
if condition ; then
command
fi
Thí dụ:
#!/bin/bash
DOGNAME=Roger
if [ "$DOGNAME" == "" ]; then
echo "Not a valid dog name!"
else
echo "Your dog name is $DOGNAME"
fi
Chú ý dấu ngoặc? Chúng ta phải thêm dấu ngoặc khi chúng ta phải thực hiện bất kỳ loại đánh giá nào của một biểu thức boolean.
Vòng lặp
Trong khi lặp lại
Trong khicondition
giải quyết thành một giá trị thực, chạycommand
while condition
do
command
done
Cho đến khi
Cho đến khicondition
giải quyết thành một giá trị thực, chạycommand
until condition
do
command
done
Tại
Lặp lại danh sách và thực hiện lệnh cho từng mục
for item in list
do
command
done
Ngắt và tiếp tục
Bên trong các vòng lặp, bạn có thể sử dụngbreak
vàcontinue
để phá vỡ hoàn toàn vòng lặp hoặc chỉ bỏ qua lần lặp hiện tại.
Trường hợp
Cấu trúc kiểm soát trường hợp cho phép bạn chọn các tuyến đường khác nhau tùy thuộc vào một giá trị.
case value in
a)
command
#...
;;
b)
command
#...
;;
esac
Thích vớifi
,esac
kết thúc cấu trúc trường hợp và như bạn có thể nhận thấy nócase
nói ngược.
Chúng tôi thêm dấu chấm phẩy kép sau mỗi trường hợp.
A*)
trường hợp sẽ xử lý tất cả các trường hợp không được thể hiện rõ ràng. Sử dụng một|
biểu tượng bạn có thể thể hiện nhiều lựa chọn cho một trường hợp duy nhất.
Thí dụ:
#!/bin/bash
read -p "How many shoes do you have?" value
case $value in
0|1)
echo "Not enough shoes! You can't walk"
;;
2)
echo "Awesome! Go walk!"
#...
;;
*)
echo "You got more shoes than you need"
#...
;;
esac
Lựa chọn
Aselect
cấu trúc hiển thị cho người dùng một menu các lựa chọn để chọn:
select item in list
do
command
done
Thí dụ:
#!/bin/bash
select breed in husky setter "border collie" chiwawa STOP
do
if [ "$breed" == "" ]; then
echo Please choose one;
else
break
fi
done
echo “You chose $breed”
Điều kiện thử nghiệm
Tôi đã sử dụng thuật ngữ nàycondition
trong các cấu trúc điều khiển trên.
Bạn có thể dùngtest
Lệnh tích hợp sẵn Bash để kiểm tra một điều kiện và trả về giá trị true (0
) hoặc giá trị sai (không phải0
).
Đây là một ví dụ:
#!/bin/bash
if test "apples" == "apples"
then
echo Apples are apples
fi
if ! test “apples” == “oranges”
then
echo Apples are not oranges
fi
Đọc đầu vào từ dòng lệnh
Bạn có thể làm cho các tập lệnh của mình trở nên tương tác bằng cách sử dụngread
lệnh cài sẵn. Lệnh này đọc một dòng từ đầu vào chuẩn và nó có thể định dạng đầu vào theo cách rất linh hoạt.
Cách sử dụng đơn giản nhất là:
echo "Age:"
read age
điều này sẽ in ra “Tuổi:” và bạn có thể nhập một số, nhấn enter và số đó sẽ được gán choage
Biến đổi.
Các-p
tùy chọn củaread
cung cấp lời nhắc tích hợp và đặt đầu vào trongage
Biến đổi:
read -p "Age: " age
Cácread
lệnh có nhiều tùy chọn khác mà bạn có thể kiểm tra bằng cách gõhelp read
trong Bash.
Thêm tùy chọn
Các tùy chọn được chỉ định bằng dấu gạch ngang, theo sau là một chữ cái, như sau:
ls -a
driveCar -b "Ford"
Trong mã của bạn, bạn sử dụng lệnh tích hợpgetopts
để phân tích cú pháp các tùy chọn và nhận giá trị.
Nếu chúng tôi chấp nhận các tùy chọna
vàb
, chúng tôi ăngetopts ab
đến một vòng lặp trong khi.
Nếu tùy chọnb
chấp nhận một giá trị, chúng tôi thêm dấu hai chấm:
sau nó, vì vậy chúng tôi định dạnggetopts
gọi như thế này:getopts ab: arg
Đây là một đoạn mã:
while getopts xy: arg
do
case $arg in
x) echo "Option $arg enabled" ;;
y) echo "The value of $arg is $OPTARG" ;;
esac
done
Trong tập lệnh này,$OPTARG
được tự động gán ký tự tùy chọn. Chúng tôi nóigetopts
tùy chọn nào chúng tôi chấp nhận và chúng tôi xử lý từng trường hợp riêng biệt.
Các lỗi được xử lý tự động bởigetopts
. Chúng ta có thể chọn tự xử lý các thông báo lỗi bằng cách thêm dấu hai chấm trước:
trước định nghĩa đối số:getopts :xy: arg
.
Sau đó, chúng tôi cũng xử lý\?
và:
các trường hợp. Tùy chọn đầu tiên được gọi khi chúng tôi vượt qua một tùy chọn không hợp lệ và tùy chọn thứ hai được gọi khi chúng tôi bỏ lỡ một tùy chọn:
while getopts :xy: arg
do
case $arg in
x) echo "Option $arg enabled" ;;
y) echo "The value of $arg is $OPTARG" ;;
:) echo "$0: Must supply an argument to -$OPTARG." >&2
exit 1 ;;
\?) echo "Invalid option -$OPTARG ignored." >&2 ;;
esac
done
Bây giờ nếu bạn bỏ lỡ thêm một đối số, các thông báo lỗi sẽ khác.
Làm việc với các tham số
Bên trong một tập lệnh, bạn có thể truy cập bất kỳ tham số nào đã được chuyển vào thời điểm gọi. Bạn truy cập chúng bằng cách sử dụng$0
,$1
,$2
và như vậy, tùy thuộc vào vị trí, nơi$0
là tên của lệnh và tăng số vị trí của tham số được tăng lên. Sau vị trí 9, bạn cần dấu ngoặc nhọn:${10}
,${11}
…
Ví dụ chạy cái nàystartCar
kịch bản:
#!/bin/bash
echo $0
echo $1
như./startCar fiesta
sẽ in
./startCar
fiesta
Cái đặc biệt$*
cú pháp in tất cả các tham số và$#
số lượng tham số được truyền:
#!/bin/bash
echo $# $*
./test.sh Milan Florence Rome
3 Milan Florence Rome
Tách các tùy chọn khỏi các tham số
Nếu bạn có cả hai tùy chọn và thông số, bạn cần phải tách chúng ra. Bạn làm điều này với dấu gạch ngang:
driveCar -m "Ford Fiesta" - Milan Florence Rome
Làm việc với chuỗi
Cho một chuỗi:
dogname="Roger"
Bạn có thể lấy độ dài của nó bằng cách sử dụng${#dogname}
Luôn sử dụng dấu ngoặc kép xung quanh các chuỗi, khi làm việc với chúng, để tránh Bash giải thích các ký tự đặc biệt bên trong chúng.
Bạn có thể so sánh 2 chuỗi bằng cách sử dụng=
hoặc là==
toán tử, nó giống nhau:
"$dogname" = "$anotherdogname"
"$dogname" == "$anotherdogname"
Nó không phải là một nhiệm vụ vì các khoảng trống xung quanh=
.
Bạn cũng có thể kiểm tra sự bất bình đẳng:
"$dogname" != "$anotherdogname"
Mảng
Mảng là một danh sách các mục, được khai báo bên trong dấu ngoặc đơn:
breeds=(husky setter "border collie" chiwawa)
Bạn có thể tham chiếu bất kỳ mục nào bên trong một mảng bằng cách sử dụng dấu ngoặc vuông:
breeds[0]
breeds[1]
và bạn có thể nhận được tổng số mục bằng cú pháp đặc biệt này:
${#breeds[@]}
Các lệnh tích hợp
Cho đến nay, bạn đã thấy một số lệnh tích hợp sẵn, như sau:
test
read
echo
Bash có một số trong số họ. Bạn có thể thấy tất cả chúng bằng cách gọihelp
và sau đó, bạn có thể tìm trợ giúp cho từng lệnh bằng cách sử dụng ví dụ:help read
.
Chức năng
Cũng giống như trong JavaScript hoặc bất kỳ ngôn ngữ lập trình nào khác, bạn có thể tạo các đoạn mã nhỏ có thể tái sử dụng, đặt tên cho chúng và gọi chúng khi bạn cần.
Bash gọi họchức năng.
Bạn xác định một hàm với
function name {
}
Thí dụ:
function cleanFolder {
}
và bạn gọi nó như thế này:
cleanFolder
Bạn có thể truyền tham số cho các thư mục mà không cần khai báo chúng - bạn chỉ cần tham chiếu chúng là$1
,$2
v.v. Giống như bạn làm đối với các tham số tập lệnh:
function cleanFolder {
echo "Clean folder $1"
}
cleanFolder "/Users/flavio/Desktop"
Tải xuống miễn phí của tôiSổ tay lệnh Linux
Thêm các hướng dẫn về cli:
- Vỏ Bash
- Giới thiệu về Bash Shell Scripting
- Vỏ cá
- Shell, xem nội dung tệp khi nó được điền vào
- Cách thoát Vim
- Trình chỉnh sửa UNIX
- Các lệnh hệ thống tệp UNIX
- Hướng dẫn về Unix Shells
- Cách đặt bí danh trong macOS hoặc Linux shell
- Hướng dẫn thực hành về Homebrew
- Cách khắc phục lỗi đường dẫn nhà phát triển hoạt động không hợp lệ xcrun trong macOS
- Dòng lệnh cho người mới bắt đầu hoàn chỉnh
- Giới thiệu về Linux
- Cách tìm quy trình đang sử dụng cổng
- Các lệnh Linux: mkdir
- Các lệnh Linux: cd
- Các lệnh Linux: pwd
- Các lệnh Linux: rmdir
- Các lệnh Linux: ls
- Các lệnh Linux: mv
- Các lệnh Linux: cp
- Các lệnh Linux: ít hơn
- Các lệnh Linux: tail
- Các lệnh Linux: chạm vào
- Các lệnh Linux: cat
- Các lệnh Linux: tìm
- Các lệnh Linux: ln
- Các lệnh Linux: ps
- Các lệnh Linux: echo
- Các lệnh Linux: hàng đầu
- Các lệnh Linux: kill
- Các lệnh Linux: killall
- Các lệnh Linux: bí danh
- Các lệnh Linux: việc làm
- Các lệnh Linux: bg
- Các lệnh Linux: fg
- Các lệnh Linux: gõ
- Các lệnh Linux: cái nào
- Các lệnh Linux: whoami
- Các lệnh Linux: ai
- Các lệnh Linux: rõ ràng
- Các lệnh Linux: su
- Các lệnh Linux: sudo
- Các lệnh Linux: chown
- Các lệnh Linux: chmod
- Các lệnh Linux: passwd
- Các lệnh Linux: mở
- Các lệnh Linux: wc
- Lệnh Linux: lịch sử
- Các lệnh Linux: du
- Các lệnh Linux: umask
- Các lệnh Linux: grep
- Các lệnh Linux: man
- Các lệnh Linux: uname
- Các lệnh Linux: sắp xếp
- Các lệnh Linux: uniq
- Các lệnh Linux: diff
- Các lệnh Linux: nohup
- Các lệnh Linux: df
- Các lệnh Linux: xargs
- Các lệnh Linux: gzip
- Các lệnh Linux: gunzip
- Các lệnh Linux: ping
- Các lệnh Linux: traceroute
- Các lệnh Linux: tar
- Các lệnh Linux: export
- Các lệnh Linux: crontab
- Các lệnh Linux: dirname
- Các lệnh Linux: basename
- Các lệnh Linux: printenv
- Các lệnh Linux: env
- Hướng dẫn ngắn về trình chỉnh sửa ed
- Hướng dẫn ngắn về vim
- Hướng dẫn ngắn gọn về emacs
- Hướng dẫn ngắn về nano
- Linux, không còn dung lượng trên thiết bị
- Cách sử dụng Netcat