bash gán giá trị mặc định


135

$ {tham số: = word} Gán giá trị mặc định. Nếu tham số không được đặt hoặc null, việc mở rộng từ được gán cho tham số. Giá trị của tham số sau đó được thay thế. Các tham số vị trí và các tham số đặc biệt có thể không được chỉ định theo cách này.

Tôi nghĩ rằng tôi có thể sử dụng tính năng này để viết ${LONG_VARIABLE_NAME:=hello}thay vì lâu hơn LONG_VARIABLE_NAME=${LONG_VARIABLE_NAME:-hello}, nhưng bây giờ bash cũng cố gắng thực hiện 'xin chào' và điều đó đưa ra một lệnh không được tìm thấy. Có cách nào để tránh điều đó không? Hay tôi sẽ phải bám lấy cái sau? Ai đó có thể đưa ra một ví dụ trong đó mặc định gán thực sự hữu ích?


13
Khi trích dẫn văn bản, rất hữu ích khi bao gồm một liên kết đến nguồn.
Jonathon Reinhart

Câu trả lời:


202

Sử dụng dấu hai chấm:

: ${A:=hello}

Dấu hai chấm là một lệnh null không làm gì cả và bỏ qua các đối số của nó. Nó được tích hợp vào bash nên một quy trình mới không được tạo.


93
Tôi không thể giúp nhưng quan sát : ${A:=hello}chính xác là miễn là A=${A:-hello}. Có vẻ như cái sau ít bí truyền hơn và ý định của nó rõ ràng hơn. Việc sử dụng :, về cơ bản là không hoạt động, dường như không có gì so với cách mà OP đã làm trước đây.
Dan

5
@camh: Đồng ý. Tôi có thể thấy ở đâu, nếu bạn có nhiều biến để khởi tạo mặc định và chúng có tên dài, :cách tiếp cận sẽ được ưu tiên hơn, cả để gõ và đọc. Vâng, đây có vẻ như là một khu vực nơi Bash có thể sử dụng một chút cải tiến.
Dan

17
@DanMoulding: những gì về : ${VERY_LONG_VARIABLE_NAME:=hello}so với : VERY_LONG_VARIABLE_NAME=${VERY_LONG_VARIABLE_NAME:-hello}. Tôi hy vọng bạn sử dụng tên biến mô tả trong mã của mình :)
pieaveragy

18
Không chỉ ngắn hơn, nhưng ít bị lỗi hơn : VERY_LONG_VARIABLE_NAME=${VERY_LOGN_VARIABLE_NAME:-hello}. Giáo sư.
chepner

5
Một lợi thế của A=$A:-hellophương pháp này là nó tự ghi lại khi chạy với set -x. Nghĩa là, phép gán sẽ in như A=hellotrong khi lệnh null sẽ chỉ in giá trị ( hello).
lmsurprenant

107

Vui lòng xem tại http://www.tldp.org/LDP/abs/html/parameter-substlation.html để biết ví dụ

${parameter-default}, ${parameter:-default}

Nếu tham số không được đặt, sử dụng mặc định. Sau cuộc gọi, tham số vẫn không được đặt.
Cả hai hình thức gần như tương đương. Phần bổ sung chỉ :tạo sự khác biệt khi tham số đã được khai báo, nhưng là null.

unset EGGS
echo 1 ${EGGS-spam}   # 1 spam
echo 2 ${EGGS:-spam}  # 2 spam

EGGS=
echo 3 ${EGGS-spam}   # 3
echo 4 ${EGGS:-spam}  # 4 spam

EGGS=cheese
echo 5 ${EGGS-spam}   # 5 cheese
echo 6 ${EGGS:-spam}  # 6 cheese

${parameter=default}, ${parameter:=default}

Nếu tham số không được đặt, đặt giá trị tham số thành mặc định.
Cả hai hình thức gần như tương đương. The: chỉ tạo sự khác biệt khi tham số đã được khai báo và là null

# sets variable without needing to reassign
# colons suppress attempting to run the string
unset EGGS
: ${EGGS=spam}
echo 1 $EGGS     # 1 spam
unset EGGS
: ${EGGS:=spam}
echo 2 $EGGS     # 2 spam

EGGS=
: ${EGGS=spam}
echo 3 $EGGS     # 3        (set, but blank -> leaves alone)
EGGS=
: ${EGGS:=spam}
echo 4 $EGGS     # 4 spam

EGGS=cheese
: ${EGGS:=spam}
echo 5 $EGGS     # 5 cheese
EGGS=cheese
: ${EGGS=spam}
echo 6 $EGGS     # 6 cheese

${parameter+alt_value}, ${parameter:+alt_value}

Nếu tham số được đặt, sử dụng alt_value, khác sử dụng chuỗi null. Sau cuộc gọi, giá trị tham số không thay đổi.
Cả hai hình thức gần như tương đương. The: chỉ tạo sự khác biệt khi tham số đã được khai báo và là null

unset EGGS
echo 1 ${EGGS+spam}  # 1
echo 2 ${EGGS:+spam} # 2

EGGS=
echo 3 ${EGGS+spam}  # 3 spam
echo 4 ${EGGS:+spam} # 4

EGGS=cheese
echo 5 ${EGGS+spam}  # 5 spam
echo 6 ${EGGS:+spam} # 6 spam

20

Việc mở rộng tham số giá trị mặc định thường hữu ích trong các tập lệnh xây dựng như ví dụ dưới đây. Nếu người dùng chỉ gọi tập lệnh theo nguyên trạng, perl sẽ không được tích hợp. Người dùng phải đặt rõ ràng thành WITH_PERLmột giá trị khác với "không" để tích hợp sẵn.

$ cat defvar.sh
#!/bin/bash

WITH_PERL=${WITH_PERL:-no}

if [[ "$WITH_PERL" != no ]]; then
    echo "building with perl"
    # ./configure --enable=perl
else
    echo "not building with perl"
    # ./configure
fi

Xây dựng mà không có Perl

$ ./defvar.sh
not building with perl

Xây dựng với Perl

$ WITH_PERL=yes ./defvar.sh
building with perl
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.