Đoạn mã sau thoát với lỗi biến không liên kết. Làm thế nào để sửa lỗi này, trong khi vẫn sử dụng set -o
tùy chọn danh từ?
#!/bin/bash
set -o nounset
if [ ! -z ${WHATEVER} ];
then echo "yo"
fi
echo "whatever"
Câu trả lời:
#!/bin/bash
set -o nounset
VALUE=${WHATEVER:-}
if [ ! -z ${VALUE} ];
then echo "yo"
fi
echo "whatever"
Trong trường hợp này, VALUE
kết thúc là một chuỗi trống nếu WHATEVER
không được đặt. Chúng tôi đang sử dụng phần {parameter:-word}
mở rộng mà bạn có thể tra cứu trong phần man bash
"Mở rộng Tham số".
:-
kiểm tra xem biến chưa được đặt hay đang trống. Nếu bạn muốn kiểm tra chỉ cho dù đó là unset, sử dụng -
: VALUE=${WHATEVER-}
. Ngoài ra, một cách dễ đọc hơn để kiểm tra xem một biến là rỗng:if [ "${WHATEVER+defined}" = defined ]; then echo defined; else echo undefined; fi
$WHATEVER
chỉ chứa khoảng trắng - Hãy xem câu trả lời của tôi.
! -z
" thay vì chỉ " -n
" không?
Bạn cần phải trích dẫn các biến nếu bạn muốn nhận được kết quả như mong đợi:
check() {
if [ -n "${WHATEVER-}" ]
then
echo 'not empty'
elif [ "${WHATEVER+defined}" = defined ]
then
echo 'empty but defined'
else
echo 'unset'
fi
}
Kiểm tra:
$ unset WHATEVER
$ check
unset
$ WHATEVER=
$ check
empty but defined
$ WHATEVER=' '
$ check
not empty
"info bash"
, "${WHATEVER-}"
nên có một ":"
(ruột kết) trước khi "-"
(gạch ngang) như: "${WHATEVER:-}"
, và "${WHATEVER+defined}"
nên có một dấu hai chấm trước "+"
(cộng) như: "${WHATEVER:+defined}"
. Đối với tôi, nó hoạt động theo cả hai cách, có hoặc không có dấu hai chấm. Trên một số phiên bản của 'nix, nó có thể sẽ không hoạt động nếu không bao gồm dấu hai chấm, vì vậy nó có thể nên được thêm vào.
-
, +
, :+
, và :-
tất cả đều được hỗ trợ. Đầu tiên phát hiện xem biến đã được đặt hay chưa và biến sau phát hiện xem biến đó được đặt hay trống . From man bash
: "Việc bỏ qua dấu hai chấm sẽ chỉ dẫn đến kết quả kiểm tra đối với tham số chưa được đặt."
Làm thế nào về một tấm lót?
[ -z "${VAR:-}" ] && echo "VAR is not set or is empty" || echo "VAR is set to $VAR"
-z
kiểm tra cả biến trống hoặc chưa đặt
-z
chỉ kiểm tra nếu tham số tiếp theo trống. -z
là chỉ là một đối số của [
lệnh. Mở rộng biến xảy ra trước khi [ -z
có thể làm bất cứ điều gì.
Các giả định:
$ echo $SHELL
/bin/bash
$ /bin/bash --version | head -1
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
$ set -o nounset
Nếu bạn muốn một tập lệnh không tương tác in ra lỗi và thoát nếu một biến là null hoặc không được đặt:
$ [[ "${HOME:?}" ]]
$ [[ "${IAMUNBOUND:?}" ]]
bash: IAMUNBOUND: parameter null or not set
$ IAMNULL=""
$ [[ "${IAMNULL:?}" ]]
bash: IAMNULL: parameter null or not set
Nếu bạn không muốn tập lệnh thoát:
$ [[ "${HOME:-}" ]] || echo "Parameter null or not set."
$ [[ "${IAMUNBOUND:-}" ]] || echo "Parameter null or not set."
Parameter null or not set.
$ IAMNULL=""
$ [[ "${IAMUNNULL:-}" ]] || echo "Parameter null or not set."
Parameter null or not set.
Bạn thậm chí có thể sử dụng [
và ]
thay vì [[
và ]]
ở trên, nhưng cái sau thích hợp hơn trong Bash.
Lưu ý những gì dấu hai chấm ở trên. Từ các tài liệu :
Nói cách khác, nếu dấu hai chấm được bao gồm, toán tử kiểm tra sự tồn tại của cả tham số và giá trị của nó không phải là giá trị rỗng; nếu dấu hai chấm bị bỏ qua, toán tử chỉ kiểm tra sự tồn tại.
Rõ ràng là không cần -n
hoặc -z
.
Tóm lại, tôi thường có thể chỉ sử dụng [[ "${VAR:?}" ]]
. Theo các ví dụ, điều này sẽ in ra một lỗi và thoát ra nếu một biến là null hoặc không được đặt.
Bạn có thể dùng
if [[ ${WHATEVER:+$WHATEVER} ]]; then
nhưng
if [[ "${WHATEVER:+isset}" == "isset" ]]; then
có thể dễ đọc hơn.
=
, không ==
hỗ trợ tính di động và [
thay vì [[
nếu có thể.
set -o nounset
dành riêng cho bash. Nếu bạn đặt một #!/bin/bash
ở đầu tập lệnh của mình, thực sự tốt nhất là sử dụng các cải tiến của bash.
Mặc dù đây không phải là trường hợp sử dụng chính xác được yêu cầu ở trên, nhưng tôi thấy rằng nếu bạn muốn sử dụng nounset
(hoặc -u
) hành vi mặc định là hành vi bạn muốn: thoát khỏi nonzero bằng một thông báo mô tả.
Tôi đã mất đủ lâu để nhận ra điều này và tôi thấy rằng nó đáng được đăng tải như một giải pháp.
Nếu tất cả những gì bạn muốn là vọng lại điều gì đó khác khi thoát ra ngoài hoặc thực hiện một số hoạt động dọn dẹp, bạn có thể sử dụng bẫy.
Nhà :-
điều hành có thể là những gì bạn muốn khác.