2016-12-07 10 views
7

Xin lưu ý: có nhiều câu hỏi về cách kiểm tra một biến trình bao duy nhất trên trang web này. Câu hỏi này là về việc thử nghiệm một tập lệnh cho bất kỳ biến không xác định nào.Làm cách nào để tôi có thể làm cho bash coi biến không xác định là lỗi?

Bạn có thể sử dụng một biến không xác định trong bash mà không nhìn thấy bất kỳ lỗi tại thực hiện:

#!/bin/bash 

echo ${UNDEF_FILE} 
ls -l ${UNDEF_FILE} 

exit 0 

tôi đã tìm thấy lỗi này rất dễ. Nếu tôi muốn thay đổi tên của một biến trong một tập lệnh lớn hoặc xóa biến đó, tất cả các tham chiếu cũ trước đó sẽ gây ra lỗi trong tập lệnh. Đôi khi điều này là không rõ ràng để gỡ lỗi hoặc bạn tìm ra khi nó quá muộn.

Tại sao điều này được phép? Có cách nào để gắn cờ biến không xác định?

+0

"Lý do" quay lại khả năng tương thích với các hệ vỏ thập niên 1970. Nếu bạn quan tâm đến thực hành tốt nhất, trái với lịch sử, kiểm tra tĩnh - như với http://shellcheck.net/, cũng có sẵn để tải xuống [dưới dạng công cụ độc lập] (https://github.com/koalaman)/shellcheck) - là bạn của bạn ở đây. –

+1

Thành thật mà nói, việc mở rộng các biến không xác định sai sẽ phá vỡ nhiều thành ngữ phổ biến. '[[$ var]] & {echo" Làm điều gì đó với $ var "; } ', ví dụ, sẽ phá vỡ với' set -u': Không giống như 'set -e' (chỉ làm cho các lỗi không được kiểm tra hoặc sử dụng như điều kiện thành thất bại),' set -u' làm cho * mọi tham chiếu đến một biến không xác định một lỗi. –

+0

(Nhân tiện - các tên biến toàn bộ nằm trong không gian được xác định bởi POSIX cho các biến môi trường có ý nghĩa với hệ vỏ hoặc hệ điều hành; không gian tên của các biến chứa ít nhất một ký tự chữ thường được dành riêng cho việc sử dụng ứng dụng. cho tất cả các biến shell, chứ không phải chỉ các biến môi trường, trên tài khoản của việc thiết lập một biến shell chia sẻ một tên với một biến môi trường ghi đè lên biến sau). –

Trả lời

9

Bạn có thể sử dụng:

set -u 

vào lúc bắt đầu của kịch bản của bạn để ném một lỗi khi sử dụng các biến không xác định.

-u

Treat biến unset và các thông số khác so với các thông số đặc biệt "@" và "*" là một lỗi khi thực hiện mở rộng tham số. Nếu việc mở rộng được thử trên một biến hoặc tham số không được đặt, shell sẽ in một thông báo lỗi, và nếu không tương tác, hãy thoát với trạng thái khác 0.

+3

... tuy nhiên, đáng chú ý là tiện ích này là ... gây tranh cãi: Nhiều thành ngữ phổ biến phụ thuộc vào giá trị không xác định mở rộng thành chuỗi rỗng, vì vậy mã cần được viết rõ ràng cho khả năng tương thích 'set -u' nếu một muốn nó như vậy. –

+2

'set -o nounset' có tác dụng tương tự như' set -u' (trong Bash), và một số người thích nó. – pjh

+1

Xem [Kiểm tra nếu biến được đặt trong bash khi sử dụng "set -o nounset"] (http://stackoverflow.com/q/7832080/4154375) để biết cách xử lý các sự cố phổ biến gây ra bằng cách sử dụng 'set -u' hoặc 'set -o nounset'. – pjh

0

set -u là lựa chọn tổng quát hơn, nhưng như đã chỉ ra trong bình luận câu trả lời khác, có những vấn đề viết kịch bản shell thành ngữ với set -u chơi. Một giải pháp thay thế là tạo các mở rộng tham số tạo ra lỗi khi một biến cụ thể không được đặt.

$ echo $foo 

$ echo $? 
0 
$ echo "${foo?:no foo for yoo}" 
bash: foo: :no foo for yoo 
$ echo $? 
1 

Lỗi này sẽ khiến vỏ không tương tác thoát. Điều này cung cấp cho bạn một cách nhanh chóng để đảm bảo điều kiện lỗi sẽ không cho phép luồng điều khiển tiếp tục với giá trị không xác định. The spec không yêu cầu trình bao tương tác để thoát, mặc dù cần lưu ý rằng ngay cả trong một trình bao tương tác, bash sẽ trở về từ một cuộc gọi hàm nếu lỗi này xảy ra trong một hàm.

Các vấn đề liên quan