为另一个脚本调用一个脚本,但是如果子级调用退出,则不要退出父级


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


在这里,您正在使用.命令,该命令在当前shell中提供另一个文件。不涉及子外壳或子外壳。您是要执行 second.shthird.sh不是采购它们吗?
Celada

是的..我必须写execute而不是。./?我想忽略“退出$?” 里面的second.sh ..是可能的,无需编辑second.sh?
user3589887

Answers:


13

您在此处所做的工作包括second.shthird.sh作为子脚本在同一过程中运行,这在Shell编程中称为“采购”。. ./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"

如果您需要其他脚本来访问原始脚本中的变量和函数,而不需要修改它们,请在子外壳中调用这些脚本。子外壳程序是单独的进程,因此exit仅退出它们。

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

如果您需要使用在父脚本中second.shthird.sh在父脚本中定义的变量或函数,则需要继续采购它们。

return内置出入口仅被执行的脚本,而不是整个过程-这是包括与其他脚本之间的一些区别一个.命令,并包括其在父脚本文本。如果源脚本仅exit在顶层调用,而不是内部函数,则可以更改exitreturn。您无需使用别名即可修改脚本。

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

如果exit在内部函数中也调用if ,我认为没有一种不麻烦的方法。一种麻烦的方法是设置出口陷阱并将代码放在此处。

#!/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视为bash的“最佳实践”,因为它可以使您的代码执行得更加清楚。
马克E.汉密尔顿

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,你是完全正确的。答案已被编辑。
戴尔·安德森

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,导致第二个脚本被包含为第一个脚本的一部分。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.