Tôi có thể xuất một biến sang môi trường từ tập lệnh bash mà không tìm nguồn cung ứng không?


282

Giả sử tôi có kịch bản này

xuất khẩu .

#! /usr/bin/env bash
export VAR="HELLO, VARIABLE"

Khi tôi thực thi tập lệnh và cố gắng truy cập vào $VAR, tôi không nhận được giá trị!

echo $VAR

Có cách nào để truy cập vào $VARbằng cách chỉ thực hiện export.bash mà không tìm nguồn cung ứng không?


1
Bạn có thể thử sử dụng bí danh thay vì tập lệnh để xác định biến của mình.
jdigital

Kịch bản mà tôi đang làm việc, là một loại trình quản lý ảo java, tôi thực hiện một số tính toán sau đó tôi nên xuất $ JAVA_HOME cho env và thêm nó vào PATH.
tarrsalah

Chà, bạn có thể viết thông tin vào một tập tin và sau đó đọc lại, nhưng tìm nguồn cung ứng có vẻ dễ dàng hơn nhiều.
jdigital

7
quá trình con không thể thay đổi môi trường của cha mẹ chúng. Phụ huynh phải chọn thay đổi chính nó (bằng sourcehoặc evalhoặc ...)
glenn jackman

1
Để đọc thêm về nguồn, man sourcesẽ không hoạt động vì sourceđược tích hợp vào bash, bạn cần chạyhelp source
peterchaula

Câu trả lời:


318

Có cách nào để truy cập vào $VARbằng cách chỉ thực hiện export.bashmà không tìm nguồn cung ứng không?

Trả lời nhanh: Không.

Nhưng có một số cách giải quyết có thể.

Điều rõ ràng nhất, mà bạn đã đề cập, là sử dụng sourcehoặc .thực thi tập lệnh trong ngữ cảnh của vỏ gọi:

$ cat set-vars1.sh 
export FOO=BAR
$ . set-vars1.sh 
$ echo $FOO
BAR

Một cách khác là có tập lệnh, thay vì đặt biến môi trường, các lệnh in sẽ đặt biến môi trường:

$ cat set-vars2.sh
#!/bin/bash
echo export FOO=BAR
$ eval "$(./set-vars2.sh)"
$ echo "$FOO"
BAR

Cách tiếp cận thứ ba là có một tập lệnh đặt (các) biến môi trường của bạn bên trong và sau đó gọi một lệnh được chỉ định với môi trường đó:

$ cat set-vars3.sh
#!/bin/bash
export FOO=BAR
exec "$@"
$ ./set-vars3.sh printenv | grep FOO
FOO=BAR

Cách tiếp cận cuối cùng này có thể khá hữu ích, mặc dù nó bất tiện cho việc sử dụng tương tác vì nó không cung cấp cho bạn các cài đặt trong trình bao hiện tại của bạn (với tất cả các cài đặt và lịch sử khác mà bạn đã xây dựng).


57

Để xuất ra biến VAR trước tiên, cách làm việc hợp lý và hợp lý nhất là tìm nguồn cho biến:

. ./export.bash

hoặc là

source ./export.bash

Bây giờ khi lặp lại từ vỏ chính, nó hoạt động

 echo $VAR
HELLO, VARABLE

Bây giờ chúng tôi sẽ thiết lập lại VAR

export VAR=""
echo $VAR

Bây giờ chúng ta sẽ thực thi một tập lệnh để lấy nguồn sau đó bỏ đặt nó:

./test-export.sh 
HELLO, VARABLE
--
.

mã: mèo test-export.sh

    #!/bin/bash
    # Source env variable
    source ./export.bash

    # echo out the variable in test script
    echo $VAR

    # unset the variable 
    unset VAR
    # echo a few dotted lines
    echo "---"
    # now return VAR which is blank
    echo $VAR

Đây là một cách

XIN LƯU Ý: Việc xuất được giới hạn trong tập lệnh thực hiện xuất trong bảng điều khiển chính của bạn - theo như một công việc định kỳ, tôi sẽ thêm nó như bảng điều khiển như bên dưới ... đối với phần lệnh vẫn còn nghi vấn: đây là cách bạn sẽ làm chạy vào từ vỏ của bạn:

Trên dấu nhắc lệnh của bạn (miễn là export.bash có nhiều giá trị echo)

IFS=$'\n'; for entries in $(./export.bash); do  export $entries;  done; ./v1.sh 
HELLO THERE
HI THERE

mèo v1.sh

#!/bin/bash
echo $VAR
echo $VAR1

Bây giờ miễn là điều này là cho việc sử dụng của bạn - bạn có thể tạo các biến có sẵn cho tập lệnh của mình bất cứ lúc nào bằng cách thực hiện một bí danh bash như thế này:

myvars ./v1.sh
HELLO THERE
HI THERE

echo $VAR

.

thêm phần này vào .bashrc của bạn

function myvars() { 
    IFS=$'\n'; 
    for entries in $(./export.bash); do  export $entries;  done; 

    "$@"; 

    for entries in $(./export.bash); do variable=$(echo $entries|awk -F"=" '{print $1}'); unset $variable;
done

}

nguồn tập tin bashrc của bạn và bạn có thể làm như trên bất cứ lúc nào ...

Nhưng dù sao cũng trở lại với phần còn lại của nó ..

Điều này đã làm cho nó có sẵn trên toàn cầu sau đó thực thi tập lệnh ..

chỉ cần lặp lại nó sau đó chạy xuất khẩu trên echo!

mèo xuất khẩu

#!/bin/bash
echo "VAR=HELLO THERE"

Bây giờ trong tập lệnh hoặc bảng điều khiển của bạn chạy:

 export "$(./export.bash)"

Thử:

echo $VAR
HELLO THERE

Nhiều giá trị miễn là bạn biết những gì bạn đang mong đợi trong một tập lệnh khác bằng phương pháp trên:

mèo xuất khẩu

#!/bin/bash
echo "VAR=HELLO THERE"
echo "VAR1=HI THERE"

mèo test-export.sh

#!/bin/bash

IFS=$'\n'
for entries in $(./export.bash); do
   export $entries
done

echo "round 1"
echo $VAR
echo $VAR1

for entries in $(./export.bash); do
     variable=$(echo $entries|awk -F"=" '{print $1}');
     unset $variable
done

echo "round 2"
echo $VAR
echo $VAR1

Bây giờ kết quả

 ./test-export.sh 
round 1
HELLO THERE
HI THERE
round 2


.

và bản cập nhật cuối cùng để tự động gán đọc VARIABLES:

./test-export.sh 
Round 0 - Export out then find variable name - 
Set current variable to the variable exported then echo its value
$VAR has value of HELLO THERE
$VAR1 has value of HI THERE
round 1 - we know what was exported and we will echo out known variables
HELLO THERE
HI THERE
Round 2 - We will just return the variable names and unset them 
round 3 - Now we get nothing back

Kịch bản: cat test-export.sh

#!/bin/bash

IFS=$'\n'
echo "Round 0 - Export out then find variable name - "
echo "Set current variable to the variable exported then echo its value"
for entries in $(./export.bash); do
 variable=$(echo $entries|awk -F"=" '{print $1}');
 export $entries
 eval current_variable=\$$variable
 echo "\$$variable has value of $current_variable"
done


echo "round 1 - we know what was exported and we will echo out known variables"
echo $VAR
echo $VAR1

echo "Round 2 - We will just return the variable names and unset them "
for entries in $(./export.bash); do
 variable=$(echo $entries|awk -F"=" '{print $1}');
 unset $variable
done

echo "round 3 - Now we get nothing back"
echo $VAR
echo $VAR1

Tôi muốn xuất VAR bằng cách thực thi tệp chứ không phải bằng cách tìm nguồn.
tarrsalah

@vahid bạn nên giải thích kịch bản của bạn đang làm gì.
FDinoff

1
Tại sao không đặt biến sau khi tìm nguồn cung ứng? nó dễ dàng hơn nhiều so với nỗi đau mà bạn cố gắng gây ra cho mình sẽ cập nhật tập lệnh xuất khẩu thử nghiệm
VH

Tôi đã đưa ra một cách khác để làm điều đó Tarrsalah
VH

ok cập nhật cuối cùng - các vấn đề với phương pháp được đề xuất và giải quyết xung quanh ý tưởng bí danh bashrc có lẽ sẽ là một cách tuyệt vời
VH

22

Hành hình

set -o allexport

Bất kỳ biến nào bạn lấy từ một tệp sau này sẽ được xuất trong shell của bạn.

source conf-file

Khi bạn thực hiện xong. Điều này sẽ vô hiệu hóa chế độ allexport.

set +o allexport

7
Toàn bộ điểm của câu hỏi là "Cách xuất mà không cần nguồn". Câu trả lời này sử dụng nguồn.
Gonen I

@ekkis Vâng, nó không trả lời chính xác câu hỏi, nhưng bất cứ khi nào tôi tìm hiểu làm thế nào để xuất các biến từ một tệp, chủ đề này xuất hiện. Vì vậy, tôi chỉ cần đặt nó ở đó cho chính mình.
mdornfe1

đơn giản và dễ sử dụng điều này nên được đánh dấu là câu trả lời.
QkiZ

1
Tôi ủng hộ điều này bởi vì tuyên bố vấn đề ban đầu khiến tôi hiểu rằng đây là giải pháp cơ bản của tôi. Có tài liệu chính thức về allexport tại đây: gnu.org/software/bash/manual/html_node/The-set-Builtin.html
benjaoming

à, +1. Câu hỏi này là kết quả hàng đầu của từ khóa bash source exporttrong Google
ttimasdf

14

Tìm thấy một cách thú vị và gọn gàng để xuất các biến môi trường từ một tệp:

trong env.vars:

foo=test

kịch bản thử nghiệm:

eval `cat env.vars`
echo $foo         # => test
sh -c 'echo $foo' # => 

export eval `cat env.vars`
echo $foo         # => test
sh -c 'echo $foo' # => test

# a better one
export `cat env.vars`
echo $foo         # => test
sh -c 'echo $foo' # => test

7

Một cách giải quyết khác, tùy thuộc vào trường hợp, nó có thể hữu ích: tạo một bash khác kế thừa biến đã xuất. Đó là một trường hợp cụ thể của câu trả lời @Keith Thompson, tất cả những nhược điểm đó.

xuất khẩu.

# !/bin/bash
export VAR="HELLO, VARIABLE"
bash

Hiện nay:

./export.bash
echo $VAR

Bạn có chắc chắn rằng những gì bạn đã viết hoạt động!? Tôi tin rằng bạn phải thực thi lệnh dòng:. ./export.bash
Sir Jo Black

@Sir Jo Black, vâng, chắc chắn rồi. Dòng cuối cùng của tệp export.bash gọi bashlà con của shell hiện tại. Và kể từ khi VARđược xuất trước đó, lệnh gọi đó sẽ bao gồm biến. Tất nhiên, nếu bạn gõ exitcác VARsẽ đi ra ngoài. Bạn coi lại chưa?
Gonmator

Đồng ý! Tôi chưa thấy lời cầu khẩn đó ...: p
Sir Jo Black

1

Câu trả lời là không, nhưng đối với tôi, tôi đã làm như sau

tập lệnh: myExport

#! \bin\bash
export $1

một bí danh trong .bashrc của tôi

alias myExport='source myExport' 

Vẫn là bạn nguồn nó, nhưng có thể theo cách này nó có thể sử dụng nhiều hơn và nó thú vị cho người khác.


1

Có lẽ bạn có thể viết một hàm trong ~ / .zshrc, ~ / .bashrc.

# set my env
[ -s ~/.env ] && export MYENV=`cat ~/.env`
function myenv() { [[ -s ~/.env ]] && echo $argv > ~/.env && export MYENV=$argv }

Vì lý do sử dụng biến bên ngoài, bạn có thể tránh ghi tập tin tập lệnh.

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.