สมมติว่าฉันมีใน main.sh:
$NAME="a string"
if [ -f $HOME/install.sh ]
. $HOME/install.sh $NAME
fi
และใน install.sh:
echo $1
นี่ควรจะเป็นเสียงสะท้อน"a string"
แต่มันก็ไม่สะท้อนอะไรเลย ทำไม?
สมมติว่าฉันมีใน main.sh:
$NAME="a string"
if [ -f $HOME/install.sh ]
. $HOME/install.sh $NAME
fi
และใน install.sh:
echo $1
นี่ควรจะเป็นเสียงสะท้อน"a string"
แต่มันก็ไม่สะท้อนอะไรเลย ทำไม?
คำตอบ:
Michael Mrozekครอบคลุมปัญหาส่วนใหญ่และการแก้ไขของเขาจะทำงานได้เนื่องจากคุณใช้ Bash
คุณอาจสนใจในความจริงที่ว่าความสามารถในการแหล่งสคริปต์ด้วยอาร์กิวเมนต์เป็น bashism ในsh
หรือdash
คุณmain.sh
จะไม่ได้สะท้อนอะไรเลยเพราะข้อโต้แย้งไปยังสคริปต์ที่มาจะถูกละเว้นและ$1
จะอ้างถึงการโต้แย้งmain.sh.
เมื่อคุณแหล่งสคริปต์ในsh
มันเป็นเหมือนคุณเพียงคัดลอกและวางข้อความของสคริปต์ที่มาลงในไฟล์ที่มันมา ลองพิจารณาสิ่งต่อไปนี้ (โปรดทราบว่าฉันได้ทำการแก้ไขที่ Michael แนะนำ):
$ bash ./test.sh
A String
$ sh ./test.sh
$ sh ./test.sh "HELLO WORLD"
HELLO WORLD
ฉันเห็นข้อผิดพลาดสามข้อ:
สายงานของคุณผิด:
$NAME="a string"
เมื่อคุณกำหนดให้กับตัวแปรคุณจะไม่รวม$
; มันควรจะเป็น:
NAME="a string"
คุณกำลังขาดหายไปthen
; บรรทัดเงื่อนไขควรเป็น:
if [ -f $HOME/install.sh ]; then
คุณไม่ได้อ้าง$NAME
ถึงแม้ว่าจะมีช่องว่าง บรรทัดซอร์สควรเป็น:
. $HOME/install.sh "$NAME"
[ -f $HOME/install.sh ] && . $HOME/install.sh $NAME
; ฉันไม่ควรทำสิ่งเช่นนั้นเมื่อฉันมองหาข้อผิดพลาด
เพียงตั้งค่าพารามิเตอร์ของคุณก่อนที่จะจัดหาสคริปต์!
#!/bin/bash
NAME=${*:-"a string"}
if [[ -f install.sh ]];
then
set -- $NAME ;
. install.sh ;
fi
exit;
#!/bin/bash
echo " i am sourced by [ ${0##*/} ]";
echo " with [ $@ ] as parametr(s) ";
exit;
u@h$ ./main.sh some args
i am sourced by [ main.sh ]
with [ some args ] as parametr(s)
u@h$
--
เช่นเดียวกับพวกเขาเป็นข้อโต้แย้งคำสั่ง:set -- -v foo -l bar -j "${bin}"