2016-09-02 13 views
29

Tôi đang viết một kịch bản lệnh shell. Trong kịch bản lệnh shell này, tôi có một biến có giá trị mặc định hoặc giá trị của một biến môi trường. Tuy nhiên, biến môi trường không phải có mặt.kịch bản lệnh shell: cách kiểm tra xem biến môi trường có tồn tại không và nhận giá trị của nó?

Ví dụ, giả sử, trước khi chạy kịch bản, tôi thực hiện các hoạt động sau:

export DEPLOY_ENV=dev 

Làm thế nào để nói với kịch bản để tìm kiếm các biến môi trường này, và lưu trữ giá trị của nó trong một biến bên trong kịch bản . Hơn nữa, làm thế nào để tôi nói với kịch bản rằng nếu biến môi trường này không tồn tại, lưu trữ một biến mặc định?

+1

'DEPLOY_ENV' printenv nên làm điều đó – sjsam

+0

tôi đã cố gắng, cho mục đích thử nghiệm tempV = $ (printenv LANG) nó đã làm không in bất cứ điều gì, mặc dù hệ thống có giá trị của LANG –

+0

Tuyên bố của bạn không "in" bất cứ điều gì. Nó lưu trữ giá trị của biến môi trường 'LANG' vào biến hệ vỏ' tempV'. Đối với các đề xuất khác trong chuỗi này: Lưu ý rằng không có đề xuất nào trong số chúng, bạn có thể phân biệt, cho dù bạn có biến môi trường hay biến hệ vỏ. Nếu sự khác biệt này thực sự quan trọng, giải pháp được đề xuất bởi @sjsam nên được xem xét. – user1934428

Trả lời

57
if [[ -z "${DEPLOY_ENV}" ]]; then 
    MY_SCRIPT_VARIABLE="Some default value because DEPLOY_ENV is undefined" 
else 
    MY_SCRIPT_VARIABLE="${DEPLOY_ENV}" 
fi 

# or using a short-hand version 

[[ -z "${DEPLOY_ENV}" ]] && MyVar='default' || MyVar="${DEPLOY_ENV}" 

# or even shorter use 

MyVar="${DEPLOY_ENV:-default_value}" 
33

Bạn chỉ có thể sử dụng parameter expansion:

$ {parameter: -từ}

Nếu tham số là unset hoặc null, việc mở rộng từ được thay thế. Nếu không, giá trị của thông số được thay thế.

Vì vậy, cố gắng này:

var=${DEPLOY_ENV:-default_value} 

Ngoài ra còn có $ {parameter-word} hình thức, mà thay thế các giá trị mặc định chỉ khi tham số là unset (nhưng không phải khi nó null).

Để chứng minh sự khác biệt giữa hai:

$ unset DEPLOY_ENV 
$ echo "'${DEPLOY_ENV:-default_value}' '${DEPLOY_ENV-default_value}'" 
'default_value' 'default_value' 
$ DEPLOY_ENV= 
$ echo "'${DEPLOY_ENV:-default_value}' '${DEPLOY_ENV-default_value}'" 
'default_value' '' 
+1

Đánh bại tôi với điều đó :). Đây là cách tốt nhất để làm điều đó Tôi đoán – sjsam

+0

Kịch bản của tôi không thể đọc giá trị của DEPLOY_ENV, Để chắc chắn rằng biến môi trường tồn tại trong hệ thống, tôi đã viết printenv DEPLOY_ENV trong thiết bị đầu cuối và giá trị chính xác đã được trả lại. Tuy nhiên, tập lệnh không thể tìm nạp tập lệnh đó. –

+0

Đó chắc chắn là cách tốt nhất để làm điều đó. Dạy tôi một cái gì đó mới, quá. +! –

2

Không có sự khác biệt giữa các biến môi trường và các biến trong một kịch bản. Các biến môi trường được xác định trước đó, bên ngoài kịch bản, trước khi kịch bản được gọi. Từ quan điểm của tập lệnh, biến là một biến.

Bạn có thể kiểm tra nếu một biến được định nghĩa:

if [ -z "$a" ] 
then 
    echo "not defined" 
else 
    echo "defined" 
fi 

và sau đó thiết lập một giá trị mặc định cho các biến không xác định hoặc làm điều gì đó khác.

Kiểm tra -z cho chuỗi có độ dài bằng không (ví dụ: trống). Xem man bash và tìm phần CONDITIONAL EXPRESSIONS.

Bạn cũng có thể sử dụng set -u ở đầu tập lệnh để làm cho nó không thành công khi gặp biến không xác định, nếu bạn muốn tránh biến không xác định phá vỡ mọi thứ theo cách sáng tạo.

8

Nếu bạn không quan tâm về sự khác biệt giữa một biến unset hoặc một biến với một giá trị rỗng, bạn có thể sử dụng việc mở rộng tham số mặc định có giá trị:

foo=${DEPLOY_ENV:-default} 

Nếu bạn làm quan tâm đến sự khác biệt, hãy thả dấu hai chấm

foo=${DEPLOY_ENV-default} 

Bạn cũng có thể sử dụng toán tử -v để kiểm tra rõ ràng nếu tham số được đặt.

if [[ ! -v DEPLOY_ENV ]]; then 
    echo "DEPLOY_ENV is not set" 
elif [[ -z "$DEPLOY_ENV" ]]; then 
    echo "DEPLOY_ENV is set to the empty string" 
else 
    echo "DEPLOY_ENV has the value: $DEPLOY_ENV" 
fi 
+0

Lưu ý rằng tùy chọn '-v' được giới thiệu trong Bash 4.2 và nhiều hệ thống vẫn đang chạy các phiên bản cũ hơn của Bash. – pjh

+3

Ngay cả 'bash' 4.2 trên 5 tuổi vào thời điểm này; Tôi có xu hướng đối xử với bất cứ điều gì cũ hơn như là một trường hợp đặc biệt xứng đáng được đề cập đặc biệt trong câu hỏi. – chepner

+1

Thật đáng kinh ngạc khi thời gian trôi qua ... –

1
NEW_VAR="" 
if [[ ${ENV_VAR} && ${ENV_VAR-x} ]]; then 
    NEW_VAR=${ENV_VAR} 
else 
    NEW_VAR="new value" 
fi 
0

Tất cả các câu trả lời làm việc. Tuy nhiên, tôi đã có thêm các biến mà tôi cần để có được các tập tin sudoers như sau:

sudo visudo 
Defaults env_keep += "<var1>, <var2>, ..., <varn>" 
Các vấn đề liên quan