【问题标题】:How to detect if a shell script is called from another shell script [duplicate]如何检测是否从另一个shell脚本调用了一个shell脚本[重复]
【发布时间】:2016-01-14 21:21:14
【问题描述】:

有没有办法检测一个shell脚本是直接调用还是从另一个脚本调用。

parent.sh

#/bin/bash
echo "parent script"
./child.sh

child.sh

#/bin/bash
echo -n "child script"
[ # if child script called from parent ] && \
    echo "called from parent" || \
    echo "called directly" 

结果

./parent.sh
# parent script
# child script called from parent

./child.sh
# child script called directly

【问题讨论】:

  • 你为什么要这样做?一个聪明的系统管理员可以很容易地编写一些小的 C 程序来包装内壳脚本。
  • ./child.sh 使用自己的解释器将子脚本作为外部可执行文件运行——就像任何其他程序调用外部可执行文件一样。你当然可以做一些丑陋和脆弱的事情,比如在进程树中查找你的父 PID,但是再看一遍:丑陋和脆弱。
  • ...如果您的真正目标是不同的,即。要检测交互式调用与脚本调用,有更好的方法来做到这一点(例如,脚本调用通常不会有 TTY,除非父脚本本身由用户调用)。类似地,如果您想支持非交互式批处理模式之类的东西,好的形式是让该切换是显式的,如果不是通过参数,然后是环境变量,可以选择在不存在 TTY 的情况下自动启用。

标签: linux bash shell


【解决方案1】:

你可以像这样使用child.sh

#/bin/bash
echo "child script"

[[ $SHLVL -gt 2 ]] &&
  echo "called from parent" ||
  echo "called directly"

现在运行它:

# invoke it directly
./child.sh
child script 2
called directly

# call via parent.sh
./parent.sh
parent script
child script 3
called from parent

$SHLVL 在父 shell 中设置为 1,并且当您的脚本从另一个脚本调用时将设置为大于 2(取决于嵌套)。

【讨论】:

  • 如果父 shell 是 zsh shell 将不起作用
  • 嗯是的,这是基于bash标签
  • 不保证交互式 shell 的 SHLVL 为 1;它很可能已经更高了。示例:我的外壳中的 SHLVL 为 1,但是从 tmux 执行实际工作,并且在里面它从 2 开始。
  • 我没有使用 tmux,因为我在 OSX 上使用iTerm,但会看看我是否可以安装它