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 đúng không? (phải có một cái gì đó đơn giản hơn)
Đ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" ];
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 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 mà không chứa giá trị để:
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} ]]
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ỳ Shell 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ác ${VAR+foo}
xây dựng mở rộng thành chuỗi trống nếu VAR
không được đặt hoặc thành foo
if VAR
được đặt thành bất kỳ thứ gì (bao gồm cả chuỗi trống).
Các ${VAR-foo}
xây dựng mở rộng thành giá trị của VAR
nếu được đặt (bao gồm đặt thành chuỗi trố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ể vượt quá người dùng (ví dụ: ${COLOR-red}
nói 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 không được đặt hoặc được đặt thành chuỗi trống là do 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ì đó như -n
, sau đó một số triển khai sẽ làm sai khi đưa ra [ "${VAR}" = "" ]
vì đối số đầu tiên với [
bị hiểu nhầm là -n
toán tử, không phải là một chuỗi.
-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.
Nếu bạn quan tâm đến việc phân biệt các trường hợp đặt trạng thái trống so với trạng thái chưa đặt, hãy xem tùy chọn -u cho bash:
$ set -u
$ echo $BAR
bash: BAR: unbound variable
$ [ -z "$BAR" ] && echo true
bash: BAR: unbound variable
$ BAR=""
$ echo $BAR
$ [ -z "$BAR" ] && echo true
true
Một thay thế tôi đã thấy [ -z "$foo" ]
là những điều sau đây, 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 là set -o nounset
), sau đó bạn sẽ gặp rắc rối với cả hai phương pháp đó. 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.
Câu hỏi hỏi cách kiểm tra xem một biến có phải là một chuỗi rỗng 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à thứ tôi thực sự đang tìm kiếm là một kiểm tra như hàm rỗng trong php làm việc 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 thì trong thời điểm đó, một hàm như blank 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à false không thể được chuyển đổi trong bash, vì vậy chúng bị 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 giới thiệu:
[.__.] đ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, việc kiểm tra số 0 trong chức năng này có thể gây ra sự cố 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ỏ những kiểm tra đó chỉ để lại kiểm tra đầu tiên.
5 xu của tôi: cũng có một cú pháp ngắn hơn if ...
, cái 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 abs-guide (tìm kiếm "Ví dụ 10-7").
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" ]
phần mở rộng oneliner của duffbeer7 's giải pháp:
#! /bin/bash
[ -z "$1" ] || some_command_that_needs_$1_parameter
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
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ờ là 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).