Đối với phiên bản cũ của câu trả lời, xem phần thứ hai của câu trả lời này. Nếu bạn muốn biết về chi tiết, hãy đọc tiếp
Nguyên nhân của vấn đề
Trong chính câu hỏi, có thông tin rằng OP thấy too many arguments error
, khi được thử nghiệm bash
dường như không phải là trường hợp:
$ [ $1 != '' ] && [ $2 != '' ]
bash: [: !=: unary operator expected
Với Ubuntu /bin/sh
thực sự được liên kết /bin/dash
với nhau, lỗi được báo cáo như sau:
$ sh
$ [ $1 != '' ] && [ $2 != '' ]
sh: 1: [: !=: unexpected operator
Và độc lập /bin/test
cũng:
$ /usr/bin/test $1 != ''
/usr/bin/test: missing argument after ‘’
Sidenote: Nếu bạn đang tự hỏi đó là gì /usr/bin/test
và tại sao tôi lại sử dụng bash
và sh
, thì bạn nên biết đó [
là bí danh cho test
lệnh, cũng tồn tại dưới dạng thực thi độc lập hoặc phổ biến hơn - như là shell được tích hợp, thứ mà mỗi shell sẽ sử dụng trước . Đối với các if
câu lệnh, chúng hoạt động trên các tượng thoát lệnh, do đó tại sao [
và test
là các lệnh, với mọi thứ khác là đối số của lệnh đó - thứ tự không đúng của các đối số dòng lệnh đó dẫn đến lỗi.
Quay lại chủ đề: không rõ làm thế nào OP có lỗi không liên quan. Tuy nhiên, trong cả 3 trường hợp, vấn đề là như nhau - biến unset sẽ được coi là rỗng, do đó, cái mà shell nhìn thấy với các biến không được trích dẫn này là
[ != '' ]
mà phá vỡ cú pháp mà test
hiểu. Hãy nhớ những gì tôi đã nói về thứ tự không đúng của các đối số dòng lệnh? Do đó tại sao trích dẫn là quan trọng. Hãy bật đầu ra chẩn đoán và xem shell nào thực thi:
$ set -x
# throws error
$ [ $1 != '' ] && [ $2 != '' ]
+ '[' '!=' '' ']'
bash: [: !=: unary operator expected
# no error
$ [ "$1" != '' ] && [ "$2" != '' ] || echo null vars
+ '[' '' '!=' '' ']'
+ echo null vars
null vars
Cách tốt hơn để kiểm tra các biến unset
Một cách tiếp cận rất thường xuyên mà bạn thấy xung quanh là:
if [ "x$var1" == "x" ] && [ "x$var2" == "x" ];
then
echo "both variables are null"
fi
Để trích dẫn Gilles :
Trong ["x $ 1" = "x"], tiền tố x đảm bảo rằng x "$ 1" có thể trông giống như một toán tử, và vì vậy cách duy nhất mà shell có thể phân tích kiểm tra này là bằng cách xử lý = như một toán tử nhị phân.
Có lẽ, điều này sẽ khá di động vì tôi đã thấy những điều này trong /bin/sh
các kịch bản. Nó cũng có thể được kết hợp như trong
if [ "x${var1}${var2}" == "x" ]; then
...
fi
Tất nhiên chúng ta có thể sử dụng -z
cờ, tuy nhiên theo nghiên cứu ở một số vỏ, đặc biệt là ksh88 (theo Stephane Chazelas ), cờ này bị lỗi.
Xem thêm