检查是否从shell或其他脚本/应用程序调用了bash脚本

时间:2010-11-23 22:55:33

标签: bash scripting shell redirect

我正在编写一个bash脚本,用于将另一个命令的输出重定向到正确的位置。基本上,当从shell /命令行调用脚本时,我想将输出发送到STDOUT。但是,当bash脚本从其他应用程序(例如另一个bash脚本,某个应用程序,或者我的Awesome窗口管理器中的awesome-prompt插件)执行时,我想将输出重定向到其他地方。

bash中是否有任何方式可以查看脚本的调用方式?

4 个答案:

答案 0 :(得分:20)

试试这个:

ps -o stat= -p $PPID

如果结果包含“s”(小写),则它可以从命令行运行,也可以从脚本中反向运行。告诉那两者:

ps -o stat= -p $$
如果没有背景,

将包含“+”。

这是一张表:

Run          $$    $PPID
CL           S+    Ss
CL&          S     Ss+
Script       S+    S+
Script&      S     S
Script(&)    S     Ss
Script&(&)   S     NULL

其中(&)表示子脚本背景和&表示运行它的父脚本(这是“脚本”所指的)是后台的。 CL表示命令行。 NULL表示ps输出null,$PPID为“1”。

来自man ps

   s    is a session leader
   +    is in the foreground process group

应该注意的是,这个答案基于GNU ps,但BSD的手册页(包括OS X)表示类似的功能。 GNU ps是一种包含BSD功能的混合体。

答案 1 :(得分:8)

我相信你真正想知道的是stdout是否是一个终端。如果是,那么你可以(几乎)安全地假设它是一个交互式会话。请尝试以下代码段:

if [[ -t 1 ]]; then
        echo "Terminal"
else
        echo "Not-a-terminal"
fi

上面的[[ -t 1 ]]命令检查文件描述符1(即stdout)是否是终端。

编辑:

请注意,如果将输出传输到其他程序,这将指示非终端stdout。在这种情况下,您可能需要一个更通用的条件,它也将检查标准输入(文件描述符0):

[[ -t 0 || -t 1 ]]

答案 2 :(得分:1)

这是我改编自另一篇关于这个主题的帖子的函数。它将所有父进程与$shells变量中列出的项目进行匹配。完成后$iscli设置为0或1.如果设置为0,那么您知道它是从shell运行的,或者您认为shell足够用于此目的。如果设置为1,那么您知道涉及的程序未获批准。我想将它用于我想在shell中运行的脚本,并且当我希望为每个脚本提供不同的输出时,我会使用PHP。

在您需要$iscli来获取值之前,您当然需要在没有任何参数的情况下最初调用该函数。

function top_level_parent_pid {

    scriptname="${0##*/}"
    shells="^bash|^init|^screen|^sh|^ssh|^su|${scriptname}"

    pid=${1:-$$}
    pidname="`ps --no-heading -o %c -p ${pid}`"
    stat=($(</proc/${pid}/stat))
    ppid=${stat[3]}
    ppidname="`ps --no-heading -o %c -p ${ppid}`"
    isclitest="`echo "${ppidname}" | grep -iv -E "${shells}"`"

    until [ "${ppid}" -eq "1" ] || [ "${iscli}" = "1" ]; do

            if [[ -n "${isclitest}" ]]; then

                    iscli="1"

                 else

                    iscli="0"


                    top_level_parent_pid ${ppid}
            fi
    done
}

答案 3 :(得分:-1)

您可以使用$ PPID

这样的东西
  PARENT=`ps --no-heading -o %c -p $PPID`
  echo $PARENT

这会将PARENT变量设置为父进程名称,然后将其打印到屏幕。

然后,您可以根据$ PARENT

的值放置一些if语句

HTH