ฉันสามารถส่งออกตัวแปรไปยังสภาพแวดล้อมจากสคริปต์ทุบตีโดยไม่ต้องจัดหาได้หรือไม่


282

สมมติว่าฉันมีสคริปต์นี้

ส่งออกทุบตี :

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

เมื่อฉันรันสคริปต์และพยายามเข้าถึง$VARฉันจะไม่ได้รับค่าใด ๆ !

echo $VAR

มีวิธีเข้าถึง$VARโดยเพียงแค่รันexport.bashโดยไม่ต้องจัดหามันหรือไม่


1
คุณสามารถลองใช้นามแฝงแทนสคริปต์เพื่อกำหนดตัวแปรของคุณ
jdigital

สคริปต์ที่ฉันทำงานอยู่เป็นตัวจัดการเสมือน java บางอย่างฉันทำการคำนวณบางอย่างจากนั้นฉันควรส่งออก $ JAVA_HOME ไปยัง env และผนวกเข้ากับ PATH
tarrsalah

คุณสามารถเขียนข้อมูลลงในไฟล์แล้วอ่านกลับ แต่การจัดหาดูเหมือนง่ายกว่ามาก
jdigital

7
กระบวนการลูกไม่สามารถเปลี่ยนแปลงสภาพแวดล้อมของผู้ปกครอง ผู้ปกครองมีให้เลือกที่จะเปลี่ยนแปลงตัวเอง (ทั้งที่มีsourceหรือevalหรือ ... )
เกล็น Jackman

1
หากต้องการอ่านเพิ่มเติมเกี่ยวกับแหล่งที่มาman sourceจะไม่ทำงานเพราะsourceถูกสร้างขึ้นในทุบตีคุณต้องเรียกใช้help source
peterchaula

คำตอบ:


318

มีวิธีเข้าถึง$VARโดยเพียงแค่ดำเนินการexport.bashโดยไม่ต้องจัดหาหรือไม่

คำตอบด่วน: ไม่

แต่มีวิธีแก้ไขหลายวิธีที่เป็นไปได้

สิ่งที่ชัดเจนที่สุดซึ่งคุณได้กล่าวไปแล้วคือการใช้sourceหรือ.ดำเนินการสคริปต์ในบริบทของการเรียกเชลล์:

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

อีกวิธีหนึ่งคือการมีสคริปต์แทนที่จะตั้งค่าตัวแปรสภาพแวดล้อมให้พิมพ์คำสั่งที่จะตั้งค่าตัวแปรสภาพแวดล้อม:

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

วิธีที่สามคือการมีสคริปต์ที่ตั้งค่าตัวแปรสภาพแวดล้อมของคุณภายในแล้วเรียกใช้คำสั่งที่ระบุกับสภาพแวดล้อมนั้น:

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

วิธีการสุดท้ายนี้มีประโยชน์มากแม้ว่าจะไม่สะดวกสำหรับการใช้แบบอินเทอร์แอคทีฟเนื่องจากมันไม่ได้ให้การตั้งค่าในเชลล์ปัจจุบันของคุณ (ด้วยการตั้งค่าและประวัติอื่น ๆ ทั้งหมดที่คุณสร้างขึ้น)


57

เพื่อที่จะส่งออกตัวแปร VAR ก่อนตรรกะที่มากที่สุดและดูเหมือนว่าวิธีการทำงานคือการจัดหาตัวแปร:

. ./export.bash

หรือ

source ./export.bash

ตอนนี้เมื่อสะท้อนจากเปลือกหลักมันทำงาน

 echo $VAR
HELLO, VARABLE

ตอนนี้เราจะรีเซ็ต VAR

export VAR=""
echo $VAR

ตอนนี้เราจะเรียกใช้งานสคริปต์ไปยังแหล่งที่มาของตัวแปรแล้วยกเลิกการตั้งค่า:

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

รหัส: cat 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

นี่คือวิธีหนึ่ง

โปรดทราบ: การส่งออกถูก จำกัด ให้สคริปต์ที่ดำเนินการส่งออกในคอนโซลหลักของคุณ - ตราบใดที่งาน cron ฉันจะเพิ่มมันเหมือนคอนโซลด้านล่าง ... สำหรับส่วนคำสั่งยังคงเป็นที่น่าสงสัย: นี่คือวิธีที่คุณจะ ทำงานจากเปลือกของคุณ:

บนพรอมต์คำสั่งของคุณ (ตราบใดที่ export.bash มีหลายค่า echo)

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

cat v1.sh

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

ตอนนี้ตราบเท่าที่นี่สำหรับการใช้งานของคุณ - คุณสามารถทำให้ตัวแปรพร้อมใช้งานสำหรับสคริปต์ของคุณได้ตลอดเวลาโดยทำนามแฝงทุบตีเช่นนี้

myvars ./v1.sh
HELLO THERE
HI THERE

echo $VAR

.

เพิ่มลงใน. bashrc ของคุณ

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

}

แหล่งไฟล์ bashrc ของคุณและคุณสามารถทำเช่นนี้ได้ทุกเมื่อ ...

อย่างไรก็ตามกลับไปที่เหลือของมัน ..

สิ่งนี้ทำให้ใช้ได้ทั่วโลกจากนั้นเรียกใช้สคริปต์ ..

เพียงแค่ก้องออกมาจากนั้นเรียกใช้การส่งออกในเสียงสะท้อน!

แมวส่งออกทุบตี

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

ขณะนี้อยู่ในสคริปต์หรือคอนโซลของคุณทำงาน:

 export "$(./export.bash)"

ลอง:

echo $VAR
HELLO THERE

หลายค่าตราบใดที่คุณรู้ว่าคุณคาดหวังอะไรในสคริปต์อื่นโดยใช้วิธีการด้านบน:

แมวส่งออกทุบตี

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

cat 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

ตอนนี้ผลลัพธ์

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


.

และอัปเดตครั้งสุดท้ายเพื่อกำหนดอัตโนมัติให้อ่านตัวแปร:

./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

สคริปต์: 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

ฉันต้องการส่งออก VAR โดยเรียกใช้งานไฟล์ไม่ใช่โดยการจัดหา
tarrsalah

@vahid คุณควรอธิบายว่าสคริปต์ของคุณทำอะไรอยู่
FDinoff

1
ทำไมไม่ตั้งค่าตัวแปรหลังจากทำการจัดหา? มันง่ายกว่าความเจ็บปวดที่คุณพยายามทำให้ตัวเองจะอัปเดตสคริปต์ทดสอบส่งออก
VH

ฉันเลือกวิธีอื่นในการทำ Tarrsalah
VH

ok การปรับปรุงครั้งสุดท้าย - ปัญหาเกี่ยวกับวิธีการที่แนะนำและหลีกเลี่ยงความคิดนามแฝง bashrc อาจจะเป็นวิธีที่ดีออกมา
VH

22

ปฏิบัติ

set -o allexport

ตัวแปรใด ๆ ที่คุณมาจากไฟล์หลังจากนี้จะถูกส่งออกในเปลือกของคุณ

source conf-file

เมื่อคุณทำสำเร็จ สิ่งนี้จะปิดใช้งานโหมด allexport

set +o allexport

7
จุดทั้งหมดของคำถามคือ "วิธีการส่งออกโดยไม่มีแหล่งที่มา" คำตอบนี้ใช้แหล่งที่มา
Gonen ฉัน

@ekkis ใช่มันไม่ได้ตอบคำถาม แต่เมื่อใดก็ตามที่ฉัน googled วิธีการส่งออกตัวแปรจากไฟล์ที่หัวข้อนี้เกิดขึ้น ดังนั้นฉันแค่วางมันไว้ที่นั่นเพื่อตัวฉันเอง
mdornfe1

ง่ายและใช้งานง่าย ควรทำเครื่องหมายเป็นคำตอบ
QkiZ

1
ฉันลงเอยนี้เพราะคำแถลงปัญหาดั้งเดิมทำให้ฉันเข้าใจว่านี่เป็นคำตอบพื้นฐานของฉัน มีเอกสารอย่างเป็นทางการใน allexport นี่: gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
benjaoming

อ๊ะ +1 คำถามนี้เป็นผลลัพธ์สูงสุดของคำหลักbash source exportใน Google
ttimasdf

14

พบวิธีการส่งออกตัวแปรสภาพแวดล้อมที่น่าสนใจและเป็นระเบียบจากไฟล์:

ในenv.vars:

foo=test

สคริปต์ทดสอบ:

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

วิธีแก้ปัญหาอื่นที่ขึ้นอยู่กับกรณีอาจเป็นประโยชน์: สร้าง bash อื่นที่สืบทอดตัวแปรที่ส่งออก มันเป็นกรณีเฉพาะของ @Keith Thompson คำตอบจะเป็นข้อเสียทั้งหมด

export.bash:

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

ขณะนี้:

./export.bash
echo $VAR

คุณแน่ใจหรือว่าสิ่งที่คุณเขียนได้ผล! ฉันเชื่อว่าคุณต้องรันคำสั่ง line:. ./export.bash
Sir Jo Black

@ Sir Jo Black ใช่แน่นอน บรรทัดสุดท้ายของไฟล์ export.bash เรียกใช้bashเป็นชายด์ของเชลล์ปัจจุบัน และตั้งแต่ที่VARถูกส่งออกมาก่อนหน้านี้การร้องขอนั้นจะรวมตัวแปร แน่นอนถ้าคุณพิมพ์exitความVARประสงค์จะออกไป คุณตรวจสอบแล้วหรือยัง
Gonmator

ตกลง! ฉันไม่เห็นคำภาวนานั้น ... : p
Sir Jo Black

1

คำตอบคือไม่ แต่สำหรับฉันฉันทำต่อไปนี้

สคริปต์: myExport

#! \bin\bash
export $1

นามแฝงใน. bashrc ของฉัน

alias myExport='source myExport' 

คุณยังคงหาแหล่งที่มา แต่บางทีด้วยวิธีนี้มันมีประโยชน์มากกว่าและน่าสนใจสำหรับคนอื่น


1

บางทีคุณสามารถเขียนฟังก์ชันใน ~ / .zshrc, ~ / .bashrc

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

เนื่องจากตัวแปรการใช้ภายนอกคุณสามารถหลีกเลี่ยงการเขียนไฟล์สคริปต์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.