Cách tốt nhất để xác định xem một biến trong bash có trống không ("") không?
Tôi đã nghe nói rằng tôi nên làm if [ "x$variable" = "x" ]
Đó có phải là cách chính xác ? (phải có một cái gì đó đơn giản hơn)
Cách tốt nhất để xác định xem một biến trong bash có trống không ("") không?
Tôi đã nghe nói rằng tôi nên làm if [ "x$variable" = "x" ]
Đó có phải là cách chính xác ? (phải có một cái gì đó đơn giản hơn)
Câu trả lời:
Điều này sẽ trả về true nếu một biến không được đặt hoặc được đặt thành chuỗi rỗng ("").
if [ -z "$VAR" ];
if [ ! -z "$VAR" ];
-z
là-n
if [ -n "$VAR" ];
$var
trên một dòng lệnh sẽ được phân chia bởi khoảng trắng của nó thành một danh sách các tham số, trong khi "$var"
sẽ luôn chỉ là một tham số. Trích dẫn các biến thường là một cách thực hành tốt và ngăn bạn khỏi vấp vào tên tệp chứa khoảng trắng (trong số những thứ khác). Ví dụ: sau khi thực hiện a="x --help"
, hãy thử cat $a
- nó sẽ cung cấp cho bạn trang trợ giúp cat
. Sau đó thử cat "$a"
- nó sẽ (thường) nói cat: x --help: No such file or directory
. Tóm lại, trích dẫn sớm và trích dẫn thường xuyên và bạn sẽ gần như không bao giờ hối tiếc.
Trong Bash, khi bạn không quan tâm đến tính di động đối với các shell không hỗ trợ nó, bạn nên luôn luôn sử dụng cú pháp ngoặc kép:
Bất kỳ điều nào sau đây:
if [[ -z $variable ]]
if [[ -z "$variable" ]]
if [[ ! $variable ]]
if [[ ! "$variable" ]]
Trong Bash, sử dụng dấu ngoặc vuông, dấu ngoặc kép không cần thiết. Bạn có thể đơn giản hóa kiểm tra cho một biến có chứa giá trị thành:
if [[ $variable ]]
Cú pháp này tương thích với ksh (ít nhất là ksh93, dù sao đi nữa). Nó không hoạt động trong POSIX thuần túy hoặc các vỏ Bourne cũ hơn như sh hoặc dash.
Xem câu trả lời của tôi ở đây và BashFAQ / 031 để biết thêm thông tin về sự khác biệt giữa dấu ngoặc kép và dấu ngoặc đơn.
Bạn có thể kiểm tra xem một biến có được đặt riêng hay không (như phân biệt với một chuỗi rỗng):
if [[ -z ${variable+x} ]]
trong đó "x" là tùy ý.
Nếu bạn muốn biết liệu một biến là null nhưng không bỏ đặt:
if [[ -z $variable && ${variable+x} ]]
if [[ $variable ]]
làm việc tốt với tôi, và thậm chí không cần đến set -u
một trong những giải pháp được đề xuất khác.
sh
thay vì Bash. Nếu bạn cần các khả năng gia tăng mà nó cung cấp, hãy sử dụng Bash và sử dụng nó đầy đủ.
;
cuối cùng. Có then
thể ở dòng tiếp theo mà không có dấu chấm phẩy nào cả.
Một biến trong bash (và bất kỳ shell tương thích POSIX nào) có thể ở một trong ba trạng thái:
Hầu hết thời gian bạn chỉ cần biết nếu một biến được đặt thành một chuỗi không trống, nhưng đôi khi điều quan trọng là phải phân biệt giữa không đặt và đặt thành chuỗi trống.
Sau đây là các ví dụ về cách bạn có thể kiểm tra các khả năng khác nhau và nó hoạt động trong bash hoặc bất kỳ trình bao tương thích POSIX nào:
if [ -z "${VAR}" ]; then
echo "VAR is unset or set to the empty string"
fi
if [ -z "${VAR+set}" ]; then
echo "VAR is unset"
fi
if [ -z "${VAR-unset}" ]; then
echo "VAR is set to the empty string"
fi
if [ -n "${VAR}" ]; then
echo "VAR is set to a non-empty string"
fi
if [ -n "${VAR+set}" ]; then
echo "VAR is set, possibly to the empty string"
fi
if [ -n "${VAR-unset}" ]; then
echo "VAR is either unset or set to a non-empty string"
fi
Đây là điều tương tự nhưng ở dạng bảng tiện dụng:
+-------+-------+-----------+
VAR is: | unset | empty | non-empty |
+-----------------------+-------+-------+-----------+
| [ -z "${VAR}" ] | true | true | false |
| [ -z "${VAR+set}" ] | true | false | false |
| [ -z "${VAR-unset}" ] | false | true | false |
| [ -n "${VAR}" ] | false | false | true |
| [ -n "${VAR+set}" ] | false | true | true |
| [ -n "${VAR-unset}" ] | true | false | true |
+-----------------------+-------+-------+-----------+
Cấu ${VAR+foo}
trúc mở rộng thành chuỗi trống nếu VAR
không được đặt hoặc thành foo
nếu VAR
được đặt thành bất kỳ thứ gì (bao gồm cả chuỗi trống).
Cấu ${VAR-foo}
trúc mở rộng thành giá trị của VAR
if set (bao gồm cả set thành chuỗi rỗng) và foo
nếu không được đặt. Điều này hữu ích để cung cấp các giá trị mặc định có thể ghi đè của người dùng (ví dụ: ${COLOR-red}
nói là sử dụng red
trừ khi biến COLOR
đã được đặt thành một cái gì đó).
Lý do tại sao [ x"${VAR}" = x ]
thường được đề xuất để kiểm tra xem một biến là không được đặt hoặc được đặt thành chuỗi trống là vì một số triển khai của [
lệnh (còn được gọi là test
) là lỗi. Nếu VAR
được đặt thành một cái gì đó giống như -n
, thì một số triển khai sẽ làm sai khi được đưa ra [ "${VAR}" = "" ]
bởi vì đối số đầu tiên [
được hiểu sai là -n
toán tử, không phải là một chuỗi.
[ -z "${VAR-set}" ]
.
set -u
hoặc set -o nounset
trong bash, thì thử nghiệm sẽ chỉ dẫn đến lỗi "bash: VAR: biến không liên kết". Xem stackoverflow.com/a/13864829 để kiểm tra unset đáng tin cậy hơn. Đi để kiểm tra xem một biến là null hay không đặt là [ -z "${VAR:-}" ]
. Kiểm tra của tôi cho dù một biến là không trống là [ "${VAR:-}" ]
.
-z
là một cách tốt nhất
Một tùy chọn khác mà tôi đã sử dụng là đặt một biến, nhưng nó có thể bị ghi đè bởi một biến khác, vd
export PORT=${MY_PORT:-5432}
Nếu $MY_PORT
biến trống, sau đó PORT
được đặt thành 5432, nếu không PORT được đặt thành giá trị của MY_PORT
. Lưu ý cú pháp bao gồm dấu hai chấm và dấu gạch ngang.
set -o nounset
trong một số kịch bản.
Một thay thế mà tôi đã thấy [ -z "$foo" ]
là như sau, tuy nhiên tôi không chắc tại sao mọi người sử dụng phương pháp này, có ai biết không?
[ "x${foo}" = "x" ]
Dù sao, nếu bạn không cho phép các biến không đặt (bằng set -u
hoặc hoặc set -o nounset
), thì bạn sẽ gặp rắc rối với cả hai phương thức đó. Có một cách khắc phục đơn giản cho vấn đề này:
[ -z "${foo:-}" ]
Lưu ý: điều này sẽ để lại biến của bạn undef.
-z
tại pubs.opengroup.org/onlinepub/009695399/utilities/test.html . Về cơ bản, nó không có nghĩa là một thay thế cho -z
. Thay vào đó, nó xử lý các trường hợp $foo
có thể mở rộng sang thứ gì đó bắt đầu bằng metacharacter [
hoặc test
sẽ bị nhầm lẫn. Đặt một vi khuẩn không metacharacter tùy ý ngay từ đầu sẽ loại bỏ khả năng đó.
Câu hỏi hỏi làm thế nào để kiểm tra xem một biến có phải là một chuỗi rỗng hay không và câu trả lời tốt nhất đã được đưa ra cho điều đó.
Nhưng tôi đã hạ cánh ở đây sau một thời gian thông qua lập trình bằng php và điều tôi thực sự tìm kiếm là một kiểm tra giống như hàm trống trong php hoạt động trong bash shell.
Sau khi đọc các câu trả lời tôi nhận ra rằng tôi đã không suy nghĩ đúng đắn về bash, nhưng dù sao đi nữa, một hàm như trống trong php sẽ rất tiện trong mã bash của tôi.
Vì tôi nghĩ điều này có thể xảy ra với người khác, tôi quyết định chuyển đổi hàm trống php trong bash
Theo hướng dẫn sử dụng php :
một biến được coi là trống nếu nó không tồn tại hoặc nếu giá trị của nó là một trong những điều sau đây:
Tất nhiên các trường hợp null và sai không thể được chuyển đổi trong bash, vì vậy chúng được bỏ qua.
function empty
{
local var="$1"
# Return true if:
# 1. var is a null string ("" as empty string)
# 2. a non set variable is passed
# 3. a declared variable or array but without a value is passed
# 4. an empty array is passed
if test -z "$var"
then
[[ $( echo "1" ) ]]
return
# Return true if var is zero (0 as an integer or "0" as a string)
elif [ "$var" == 0 2> /dev/null ]
then
[[ $( echo "1" ) ]]
return
# Return true if var is 0.0 (0 as a float)
elif [ "$var" == 0.0 2> /dev/null ]
then
[[ $( echo "1" ) ]]
return
fi
[[ $( echo "" ) ]]
}
Ví dụ về cách sử dụng:
if empty "${var}"
then
echo "empty"
else
echo "not empty"
fi
Bản trình diễn:
đoạn trích sau:
#!/bin/bash
vars=(
""
0
0.0
"0"
1
"string"
" "
)
for (( i=0; i<${#vars[@]}; i++ ))
do
var="${vars[$i]}"
if empty "${var}"
then
what="empty"
else
what="not empty"
fi
echo "VAR \"$var\" is $what"
done
exit
đầu ra:
VAR "" is empty
VAR "0" is empty
VAR "0.0" is empty
VAR "0" is empty
VAR "1" is not empty
VAR "string" is not empty
VAR " " is not empty
Đã nói rằng trong logic bash, các kiểm tra về số 0 trong hàm này có thể gây ra các vấn đề phụ, bất kỳ ai sử dụng chức năng này nên đánh giá rủi ro này và có thể quyết định cắt bỏ các kiểm tra đó chỉ để lại kiểm tra đầu tiên.
empty
- tại sao bạn viết [[ $( echo "1" ) ]] ; return
thay vì đơn giản return 1
?
toàn bộ if-then và -z là không cần thiết.
["$ foo"] && echo "foo không trống" ["$ foo"] || echo "foo thực sự trống rỗng"
Điều này đúng chính xác khi $ FOO được đặt và trống:
[ "${FOO+x}" = x ] && [ -z "$FOO" ]
Cá nhân thích cách rõ ràng hơn để kiểm tra:
if [ "${VARIABLE}" == "" ]; then
echo VARIABLE is empty
else
echo VARIABLE is not empty
fi
oneliner mở rộng giải pháp của duffbeer703 :
#! /bin/bash
[ -z "$1" ] || some_command_that_needs_$1_parameter
5 xu của tôi: cũng có một cú pháp ngắn hơn, cú pháp if ...
này:
VALUE="${1?"Usage: $0 value"}"
Dòng này sẽ đặt GIÁ TRỊ nếu một đối số đã được cung cấp và sẽ in một thông báo lỗi được thêm vào số dòng kịch bản trong trường hợp có lỗi (và sẽ chấm dứt thực thi tập lệnh).
Một ví dụ khác có thể được tìm thấy trong hướng dẫn abs (tìm kiếm «Ví dụ 10-7»).
Không phải là một câu trả lời chính xác, nhưng chạy vào thủ thuật này. Nếu chuỗi bạn đang tìm kiếm đến từ "một lệnh" thì bạn thực sự có thể lưu trữ lệnh trong một env. biến và sau đó thực hiện nó mỗi lần cho câu lệnh if, sau đó không yêu cầu dấu ngoặc!
Ví dụ: lệnh này, xác định nếu bạn đang dùng debian:
grep debian /proc/version
ví dụ đầy đủ:
IS_DEBIAN="grep -i debian /proc/version"
if $IS_DEBIAN; then
echo 'yes debian'
else
echo 'non debian'
fi
Vì vậy, đây giống như một cách gián tiếp (chạy lại mỗi lần) để kiểm tra một chuỗi rỗng (tình cờ kiểm tra phản hồi lỗi từ lệnh, nhưng nó cũng xảy ra khi trả về một chuỗi rỗng).