thiết lập -u sử dụng không hoạt động như mong đợi


12

Tôi đang tìm hiểu cách sử dụng hiệu quả các settùy chọn khác nhau trong tập lệnh của mình và tình cờ set -uthấy nó hoàn hảo để thoát khỏi tập lệnh của tôi nếu một biến không được đặt đúng (ví dụ: xóa người dùng). Theo trang người đàn ông , set -uset -ethực hiện như sau ...

-e  Exit immediately if a command exits with a non-zero status.
-u  Treat unset variables as an error when substituting.

Tôi đã tạo một tập lệnh thử nghiệm để kiểm tra chức năng này, nhưng nó dường như không hoạt động như mong đợi. Có lẽ ai đó có thể giải thích tốt hơn vấn đề của tôi cho tôi và nơi tôi đang diễn giải sai? Kịch bản thử nghiệm là dưới đây. Cảm ơn bạn.

set -e
set -u
testing="This works"
echo $?
echo ${testing}
testing2=
echo $?
echo ${testing2}
testing3="This should not appear"
echo $?
echo ${testing3}

Tôi hy vọng tập lệnh hiển thị 0"Điều này hoạt động" , và sau đó thất bại vì ${testing2}không được đặt.

Thay vào đó tôi được hiển thị 0"Điều này hoạt động" , theo sau 0 và sau đó 0 Điều này sẽ không xuất hiện

Bất cứ ai có thể cung cấp một số kiến ​​thức? Cảm ơn bạn.


1
Vì vậy, theo dõi ... có cách nào để đặt một biến thành chuỗi null bất hợp pháp / gây ra lỗi không? Tôi đoán là không.
Luke Davis

Câu trả lời:


10

Từ "người đàn ông Bash":

Một tham số được đặt nếu nó đã được gán một giá trị. Chuỗi null là một giá trị hợp lệ. Khi một biến được đặt, nó chỉ có thể được hủy đặt bằng cách sử dụng lệnh dựng sẵn không đặt.

Khi bạn làm, testing2=bạn đang đặt biến thành chuỗi null.

Thay đổi nó unset testing2và thử lại.


Điều set -enày không giúp ích gì trong trường hợp này vì một bài tập không bao giờ có mã thoát là 1. Hãy thử điều này để thấy rằng lệnh cuối cùng được thực thi (bài tập) có mã thoát là 0 hoặc đọc câu hỏi này :

$ false; a=""; echo $?
0

Và tôi cũng tin rằng việc sử dụng set -e là một vấn đề mà một giải pháp.

Những gì có thể nhận được một lỗi với việc sử dụng các biến unset là set -u:

#!/bin/bash
set -u
testing="This works"
echo ${testing}
unset testing2
echo ${testing2}
testing3="This should not appear"
echo ${testing3}

Sẽ xuất:

$  ./script.sh
This works
./script.sh: line 9: testing2: unbound variable

3

testing2=đặt testing2biến thành một chuỗi rỗng; biến thực sự được đặt .

Tuy nhiên, nếu bạn chạy echo $testing99trong shell Bash tương tác (không có cài đặt errexit, nghĩa là set -e), bạn sẽ gặp lỗi:

bash: testing99: unbound variable

Qua một bên

Trong khi kiểm tra tập lệnh vừa rồi, tôi phát hiện ra rằng trình bao tương tác không phải lúc nào cũng thoát khi cố gắng mở rộng một biến chưa được đặt trong khi trình bao không tương tác (chạy tập lệnh shell) luôn thoát . Theo trang người đàn ông POSIX cho set:

-u Shell sẽ viết một thông báo đến lỗi tiêu chuẩn khi nó cố gắng mở rộng một biến không được đặt và thoát ngay lập tức. Một vỏ tương tác sẽ không thoát.

Một tương tác Bash shell sẽ không thoát khỏi trừ khi errexitcũng được thiết lập. Mặt khác, một vỏ dash tương tác sẽ không thoát - ngay cả khi set -etrước đó đã được chạy.


Nếu dấu gạch ngang không thoát với set -e; đặt -u; bỏ đặt aa; echo $ aa, sau đó dash là sai.
hỏi

@schily Khi tôi nhận thấy điều này lần đầu tiên, tôi đã hiểu rằng các tác giả gạch ngang biết rõ hơn tôi và có thể có một số sự mơ hồ trong thông số kỹ thuật POSIX nhưng đã kiểm tra lại pubs.opengroup.org/onlinepub/9699919799/utilities/ , tôi đồng ý rằng trông giống như một lỗi, được rồi
Anthony Geoghegan

Có một quy tắc đơn giản: khi cả Korn Shell và Bourne Shell đồng ý và một triển khai shell khác có độ lệch, thì lớp vỏ kia hoạt động không chính xác.
schily
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.