shell脚本是否可以通过source
来测试它是否被执行过? ?也就是说,例如,
$ source myscript.sh
$ ./myscript.sh
myscript.sh 能否区分这些不同的 shell 环境?
最佳答案
我想,山姆想做的事,或许是不可能的。
半生不熟的解决方法在多大程度上是可能的,取决于......
如果我正确理解 Sam 的要求,他想要一个“脚本”,
myscript
, 那是...myscript
(即具有 chmod a-x
); sh myscript
对用户间接执行或者调用
bash myscript
采购它:
. myscript
首先要考虑的是这些
myscript
) 调用脚本需要第一行脚本如
#!/bin/bash
或类似。这将直接决定哪个bash 可执行文件(或符号链接(symbolic link))的已安装实例将被调用以运行
脚本的内容。这将是一个新的 shell 进程。它需要
脚本文件本身设置了可执行标志。
参数 (
sh myscript
) 与“1”相同。 -- 除了可执行标志不需要设置,第一行用
也不需要 hashbang .唯一需要的是调用
用户需要对脚本文件的读取权限。
. myscript
) 来调用脚本非常适合与“1”相同。 -- 除了它不是一个被调用的新shell。一切
脚本的命令在当前 shell 中执行, 使用它的环境
(并且还使用它可能设置的任何(新)变量“污染”其环境或
改变。 (通常这是一件非常危险的事情:但在这里它可能是
用于执行
exit $RETURNVALUE
在某些条件下....) 对于“1.”:
轻松实现:
chmod a-x myscript
会阻止 myscript
从存在直接可执行。但这不会满足要求“2”。和'3.'。
对于“2”。和“3.”:
更难达到。来自
sh myscript
的调用需要阅读文件的权限。所以一个明显的出路似乎是
chmod a-r
myscript
.但是,这也将禁止“3.”:您将无法源脚本。
那么以一种使用 Bashism 的方式编写脚本呢?巴什主义是一种
做其他 shell 不理解的事情的具体方法:使用
特定的变量、命令等。这可以在脚本中使用
发现这种情况并对其“做点什么”(例如“显示警告.txt”,
“mailto admin”等)。但是在 hell 里没有办法阻止
sh
或者bash
或任何其他 shell 读取并尝试执行以下所有操作写入脚本的命令/行,除非您通过调用杀死 shell
exit
.例子:在Bash中,脚本看到的环境知道
$BASH
,$BASH_ARGV
, $BASH_COMMAND
, $BASH_SUBSHELL
, BASH_EXECUTION_STRING
……如果由
sh
调用(如果来自 sh
内),正在执行的 shell 将看到所有这些
$BASH_*
作为空的环境变量。再次,这可以使用在脚本中发现这种情况并“做某事”......但不是
防止调用以下命令!
我现在假设...
#!/bin/bash
作为第一行,下表来自 Bash,这是他们的登录 shell,
sh
可用,它是指向 bash
的符号链接(symbolic link)或 dash
. 这意味着可以使用列出的值进行以下调用
对于环境变量
vars+invok's | ./scriptname | sh scriptname | bash scriptname | . scriptname ---------------+--------------+---------------+-----------------+------------- $0 | ./scriptname | ./scriptname | ./scriptname | -bash $SHLVL | 2 | 1 | 2 | 1 $SHELLOPTS | braceexpand: | (empty) | braceexpand:.. | braceexpand: $BASH | /bin/bash | (empty) | /bin/bash | /bin/bash $BASH_ARGV | (empty) | (empty) | (empty) | scriptname $BASH_SUBSHELL | 0 | (empty) | 0 | 0 $SHELL | /bin/bash | /bin/bash | /bin/bash | /bin/bash $OPTARG | (empty) | (empty) | (emtpy) | (emtpy)
Now you could put a logic into your text script:
- If
$0
is not equal to-bash
, then do anexit $SOMERETURNVALUE
.
In case the script was called via sh myscript
or bash myscript
, then it will
exit the calling shell. In case it was run in the current shell, it will
continue to run. (Warning: in case the script has any other exit
statements,
your current shell will be 'killed'...)
So put into your non-executable myscript.txt
near its beginning something like
this may do something close to your goal:
echo BASH=$BASH
test x${BASH} = x/bin/bash && echo "$? : FINE.... You're using 'bash ...'"
test x${BASH} = x/bin/bash || echo "$? : RATS !!! -- You're not using BASH and I will kick you out!"
test x${BASH} = x/bin/bash || exit 42
test x"${0}" = x"-bash" && echo "$? : FINE.... You've sourced me, and I'm your login shell."
test x"${0}" = x"-bash" || echo "$? : RATS !!! -- You've not sourced me (or I'm not your bash login shell) and I will kick you out!"
test x"${0}" = x"-bash" || exit 33
关于bash - 判断shell脚本是否被执行 "sourcing"it,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3664225/