检查bash脚本是从shell还是其他脚本/应用程序调用
我正在编写一个bash脚本以将输出从另一个命令重定向到正确的位置。基本上,当从shell /命令行调用脚本时,我想将输出发送到STDOUT。但是,当bash脚本从其他应用程序(例如另一个bash脚本,某些应用程序或我的Awesome Window Manager中的awesome-prompt插件)执行时,我想将输出重定向到其他位置。检查bash脚本是从shell还是其他脚本/应用程序调用
在bash中有什么方法可以查看脚本是如何被调用的?
试试这个它既可以从命令行运行,也可以从脚本中运行。将这两者区分开来:
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功能的混合体。
你可以使用$ PPID
喜欢的东西
PARENT=`ps --no-heading -o %c -p $PPID`
echo $PARENT
这将设置父变量,父进程名称,然后将其打印到屏幕上。
然后,您可以把一些如果基于$父母的价值陈述
HTH
我测试了这个,不管是直接运行它还是从其他* bash *脚本打印“bash” – ndemou 2016-01-11 08:12:28
我相信,你真的想知道什么是标准输出是一个终端或没有。如果是,那么你可以(几乎)安全地假设它是一个交互式会话。尝试下面的代码片断:
if [[ -t 1 ]]; then
echo "Terminal"
else
echo "Not-a-terminal"
fi
上述[[ -t 1 ]]
命令是什么检查,如果文件描述符1(即标准输出)是终端或没有。
编辑:
请注意,这将表明一个非终端的标准输出,如果您管道输出到其他程序。如果结果中含有“S”
ps -o stat= -p $PPID
(小写):在这种情况下,你可能需要一个更灵活的条件,也将检查标准输入(文件描述符0):
[[ -t 0 || -t 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
}
查看它的另一种方法是,为什么不使用管道输出本身的包装脚本?所以,真棒窗口管理器调用script-wrapper.sh,这包含行“./script.sh >> awesome.log” – laher 2010-11-23 23:22:03
作为shell脚本的用户,我更喜欢当脚本不要太聪明。如果我想在一个文件中输出,我完全有能力把它放在一个文件中。为脚本提供封装或标志以将输出发送到文件(例如`-o filename`)将是理想的 - 容易,但明确。 – 2010-11-24 16:50:18
好点,但我希望这很简单。有问题的命令是Taskwarrior。我只想输入'task add blah blah`,不用担心输入的地方。如果我需要每次输入一系列重定向或选项,我不会使用它,因为它不够方便。 – 2010-11-26 00:53:56