SELECT LOOP trong tập lệnh shell là gì?
https://www.shell-tips.com/bash/select-loop/#gsc.tab=0
Cấu trúc
SELECT là một cách viết tắt bash để tạo một menu được đánh số. Nó không phải là một phần của tiêu chuẩn shell
POSIX. Đây là một lệnh hữu ích để dễ dàng yêu cầu người dùng chọn từ danh sách các tùy chọn.
Bất chấp tên của nó,
SELECT LOOP không phải là một phần của cấu trúc biến thể của
bash loop. Giống như từ khóa
if trong bash, từ khóa
SELECTlà một phần của cấu trúc có điều kiện trong bash shell.
Cú pháp SELECT LOOP rất gần với cú pháp của vòng lặp for:
select name [in words …]; do commands; done
Danh sách các từ sau từ khóa
in được bash shell mở rộng để tạo danh sách các mục (
menu). Các
menu được in trên luồng đầu ra lỗi tiêu chuẩn (
STDERR), đứng trước một số. Tương tự như việc dùng
loop trong bash shell, nếu
[in words …] bị bỏ qua, các tham số vị trí sẽ được sử dụng như thể sử dụng trong
"$@".
Vòng lặp chọn sử dụng biến
PS3 để nhắc người dùng. Lựa chọn của người dùng được đọc từ đầu vào tiêu chuẩn. Nếu lựa chọn của người dùng trống,
menu và lời nhắc
PS3 sẽ hiển thị lại. Nếu một số được cung cấp bởi người dùng, thì biến tên từ vòng chọn sẽ được đặt thành từ tương ứng (mục
menu). Bất kỳ giá trị nào khác được đọc đều khiến tên được đặt thành
null.
Lệnh
SELECT hoàn tất khi
EOF được đọc hoặc lệnh
break. Dòng
read (number) được lưu vào biến
REPLY.
Dưới đây là một ví dụ để nhắc người dùng chọn tên tệp từ thư mục hiện tại và hiển thị tên tệp cũng như chỉ mục của tệp đã chọn.
tạo 1 file có tên là select.sh và đưa nội dung ví dụ vào
select filename in *;
do
echo "You selected $filename ($REPLY)"
break;
done
Gán quyền thực thi cho file select.sh
chmod +x select.sh
thực thi file select.sh
root@test-scripts:~/test# ./select.sh
Kết quả như dưới
Vòng lặp SELECT có thể được lồng vào nhau để tạo các menu con, mặc dù biến nhắc nhở của PS3 không bị thay đổi khi vào vòng lặp lồng nhau. Trong trường hợp như vậy, hãy đảm bảo đặt biến PS3 tương ứng.
Làm cách nào để tạo menu chọn trong bash?
Dưới đây là một ví dụ sử dụng
SELECT LOOP để tạo menu có thể chọn từ biến thể
bash array, sử dụng biến PS3 để đặt lời nhắc người dùng và hiển thị menu và chỉ mục đã chọn.
Ví dụ: Đoạn script yêu cầu người dùng lựa chọn một con vật từ danh sách trong
option, từ khóa
select để tạo một menu từ danh sách của option. Sau đó, người dùng có thể chọn một tùy chọn từ menu bằng cách nhập số tương ứng. Đầu tiên, mã sẽ kiểm tra xem người dùng đã chọn một con vật chưa. Nếu người dùng đã chọn "
chair" hoặc "
apple", sẽ in thông báo cho biết
$menu is not an animal. Ngược lại, mã sẽ in thông báo cho biết
$menu is an animal
PS3="Choose an animal: "
options=(cat dog mouse chair cow bird apple)
select menu in "${options[@]}";
do
echo -e "\nyou picked $menu ($REPLY)"
if [[ $menu == "chair" || $menu == "apple" ]]; then
echo -e "$menu is not an animal\n"
else
echo "$menu is an animal"
break;
fi
done
- Biến PS3 được sử dụng để đặt lời nhắc sẽ được hiển thị cho người dùng. Trong trường hợp này, lời nhắc là "Choose an animal:".
- Mảng options được sử dụng để lưu trữ danh sách các tùy chọn mà người dùng có thể chọn. Trong trường hợp này, mảng chứa các mục sau: "cat", "dog", "mouse", "chair", "cow", "bird", và "apple".
- Từ khóa select được sử dụng để tạo menu từ danh sách các tùy chọn. Biến menu được sử dụng để lưu trữ tùy chọn mà người dùng chọn.
- Từ khóa do được sử dụng để bắt đầu một vòng lặp. Vòng lặp sẽ tiếp tục chạy cho đến khi người dùng chọn một tùy chọn từ menu.
- Lệnh echo được sử dụng để in một thông báo.
- Câu lệnh if được sử dụng để kiểm tra xem người dùng đã chọn một con vật hay chưa. Nếu người dùng chọn "chair" hoặc "apple", mã sẽ in thông báo cho biết $menu is not an animal. Nếu không, mã sẽ in thông báo cho biết $menu is an animal.
- Câu lệnh break dùng để thoát khỏi vòng lặp.
Khi chạy ví dụ này, kết quả đầu ra sẽ như bên dưới khi lần đầu tiên chọn tùy chọn 4 rồi chọn 1.
Sử dụng PIPE để làm đầu vào cho SELECT LOOP
Như đã đề cập trước đó, lệnh
SELECT hoàn thành khi đọc
EOF và nó đọc lựa chọn của người dùng từ
STDIN (đầu vào tiêu chuẩn là đầu vào bàn phím trong script)
Mặc dù đây không phải là trường hợp khi lệnh được đưa vào tập lệnh của bạn từ bàn phím, nhưng đầu ra tiêu chuẩn STDOUT của lệnh được trước đó sẽ trở thành STDIN.