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

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

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始终退出。如果子 shell 退出,如何避免从第一个 shell 退出?

我无法编辑second.sh

答案1

您在这里所做的是将second.shthird.sh作为在同一进程中运行的子脚本,这在 shell 编程中称为“采购”。. ./second.sh基本上相当于包含second.sh当时的文本。该exit命令退出进程,无论您是在原始脚本还是源脚本中调用它都没有关系。

如果您只想运行 和 中的命令second.shthird.sh并且它们不需要访问或修改原始脚本中的变量和函数,请将这些脚本调用为子进程。

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

如果您需要其他脚本访问原始脚本中的变量和函数,但不修改它们,请在子 shell 中调用这些脚本。子 shell 是单独的进程,因此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"

ifexit也被称为内部函数,我认为没有一个不麻烦的方法。一种麻烦的方法是设置一个退出陷阱并将代码放在那里。

#!/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

答案2

无需获取第二个和第三个 shell,只需像运行任何其他命令一样运行它们即可。如果需要,可以存储和使用退出代码,如下所示:

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

答案3

尝试这样(.在调用时先删除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导致第二个脚本被包含为第一个脚本的一部分。

答案4

脚本1.sh

  1 PWD="/scratch/currdir"
  2 echo "Hello from scrpt 1"
  3
  4 sh $PWD/script2.sh # We will exit in script2.sh and see if line 6 gets printed
  5
  6 echo "From script 1: After scrpt2 call"
  7 exit 0

脚本2.sh

  1 echo "Hello from script 2"
  2
  3 exit 1
  4 echo "This should not get printed"

输出:

-bash-4.1$ sh script1.sh
Hello from scrpt 1
Hello from script 2
From script 1: After scrpt2 call

(注意:虽然我们退出了 script2(第 3 行,退出 1),但仍在 script1.sh 中,第 6 行在调用 script2.sh 后执行

希望这可以帮助。

相关内容