เรียกสคริปต์สำหรับสคริปต์อื่น แต่อย่าออกจากพาเรนต์ถ้าลูกเรียกออก


11

first.sh:

#! /bin/ksh
echo "prova"
. ./second.sh
echo "ho lanciato il secondo"
. ./third.sh
echo "ho lanciato il terzo"

second.sh:

echo "sono nel secondo script"
dosomething1
exit $?

หากsecond.shตรวจพบข้อผิดพลาดและออกด้วยสถานะ -9 ให้first.shออกเสมอ ฉันจะหลีกเลี่ยงการออกจากเปลือกแรกได้อย่างไรถ้าเปลือกลูกออก?

second.shฉันไม่สามารถแก้ไข


ที่นี่คุณกำลังใช้.คำสั่งซึ่งแหล่งไฟล์อื่นในเปลือกปัจจุบัน ไม่มีเชลล์ย่อยหรือเชลล์ย่อยที่เกี่ยวข้อง คุณหมายถึงดำเนินการ second.shและthird.shแทนที่จะจัดหามาหรือไม่
Celada

ใช่ .. ฉันต้องเขียนคำสั่งแทน ./? ฉันต้องการละเว้น "exit $" ภายใน second.sh .. เป็นไปได้โดยไม่ต้องแก้ไข second.sh?
user3589887

คำตอบ:


13

สิ่งที่คุณทำที่นี่รวมถึงsecond.shและthird.shเป็นสคริปต์ย่อยที่ทำงานในกระบวนการเดียวกันซึ่งเรียกว่า "การจัดหา" ในการเขียนโปรแกรมเชลล์ . ./second.shโดยทั่วไปเทียบเท่ากับการรวมข้อความของsecond.shณ จุดนั้น exitคำสั่งออกจากกระบวนการที่มันไม่สำคัญว่าคุณจะเรียกมันว่าในสคริปต์เดิมหรือในสคริปต์ที่มา

หากสิ่งที่คุณต้องการจะทำคือเรียกใช้คำสั่งในsecond.shและthird.shและพวกเขาไม่จำเป็นต้องเข้าถึงหรือการปรับเปลี่ยนตัวแปรและฟังก์ชั่นจากสคริปต์เดิมเรียกสคริปต์เหล่านี้เป็นกระบวนการที่เด็ก

#! /bin/ksh
echo "prova"
./second.sh
echo "ho lanciato il secondo"
./third.sh
echo "ho lanciato il terzo"

หากคุณต้องการสคริปต์อื่น ๆ เพื่อเข้าถึงตัวแปรและฟังก์ชั่นจากสคริปต์ต้นฉบับ แต่ไม่ต้องแก้ไขให้เรียกสคริปต์เหล่านี้ใน subshells Subshells เป็นกระบวนการที่แยกกันดังนั้นexitออกจากพวกเขาเท่านั้น

#! /bin/ksh
echo "prova"
(. ./second.sh)
echo "ho lanciato il secondo"
(. ./third.sh)
echo "ho lanciato il terzo"

หากคุณต้องการใช้ตัวแปรหรือฟังก์ชั่นที่กำหนดไว้ในsecond.shและthird.shในสคริปต์หลักแล้วคุณจะต้องจัดหาพวกเขา

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

#! /bin/ksh
echo "prova"
alias exit=return
. ./second.sh
echo "ho lanciato il secondo"
. ./third.sh
unalias exit
echo "ho lanciato il terzo"

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

#!/bin/ksh
do_first () {
  echo "prova"
  trap "after_second" EXIT
  . ./second.sh
  after_second
}
after_second () {
  echo "ho lanciato il secondo"
  trap "after_third" EXIT
  . ./third.sh
  after_third
}
after_third () {
  trap - EXIT
  echo "ho lanciato il terzo"
}
do_first

ด้วยเหตุนี้ฉันจึงหยุดใช้ '.' ไปยังไฟล์ต้นฉบับลงในสคริปต์และลองใช้ 'ซอร์ส' แทนโดยเฉพาะ IMO ที่ควรได้รับการพิจารณาว่าเป็นการปฏิบัติที่ดีที่สุดเพราะมันทำให้ชัดเจนยิ่งขึ้นว่าโค้ดของคุณกำลังทำอะไรอยู่
Mark E. Hamilton

6

แทนที่จะหาเชลล์ที่สองและสามเพียงแค่รันมันตามที่คุณต้องการ รหัสทางออกสามารถจัดเก็บและใช้งานได้ตามต้องการ:

#! /bin/ksh
echo "prova"

# execute and capture stdout ... output of second is not seen ...
OUTPUT1=$(./second.sh)

# find out exit status of second.sh
STATUS1=$?

# ... until now
echo $OUTPUT1

# do something based on the result
if [ $STATUS1 -eq 0 ]; then 
  echo "second.sh ran successfully"
else 
  echo "second.sh crapped out"
fi

# and so on...

STATUS1=$?จะจับผลที่ออกมาก่อนหน้านี้คำสั่ง echo ./second.shซึ่งเป็นอิสระจากผลของ
Cromax

@Cromax คุณพูดถูก แก้ไขคำตอบแล้ว
Dale Anderson

0

ลองด้วยวิธีนี้ (ลบก่อน.โทรsecond.sh):

first.sh:

#! /bin/ksh
echo "prova"
./second.sh
echo "ho lanciato il secondo"
./third.sh
echo "ho lanciato il terzo"

second.sh:

echo "sono nel secondo script"
dosomething1
exit $?

นี่เป็นเพราะ.เป็นรหัสย่อsourceที่ทำให้สคริปต์ที่สองจะรวมเป็นส่วนหนึ่งของสคริปต์แรก

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