$ source myscript.sh $ ./myscript.sh
myscript.sh能区分这些不同的shell环境吗?
取决于什么程度的半卧室解决方法是可能的,取决于…
> …用户的默认shell,和
> …允许使用哪些替代shell。
如果我正确地理解Sam的要求,他想要一个“脚本”,
myscript,也就是…
> …不能直接执行通过调用它的名称myscript
(即具有chmod a-x);
> …不能通过调用sh myscript或者为用户间接执行
调用bash myscript
> …只有运行其包含的函数和命令(如果调用)
采购它:。 myscript
首先要考虑的是这些
>直接通过其名称(myscript)调用脚本需要第一行
脚本像#!/ bin / bash或类似。这将直接决定哪个
将调用bash可执行文件(或符号链接)的已安装实例运行
脚本的内容。这将是一个新的shell进程。它需要
scriptfile本身设置了可执行标志。
>通过调用脚本(路径)名称为的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的方式写脚本呢? Bashism是一个
具体的方式做其他shell不明白的东西:使用
特定变量,命令等。这可以在脚本内使用
发现这个条件和“做某事”(例如“display warning.txt”,
“mailto admin”等)。但是没有办法在地狱,这将防止sh或
bash或任何其他shell从阅读和尝试执行所有以下
命令/行写入脚本,除非你通过调用杀死shell
出口。
示例:在Bash中,脚本所看到的环境知道$ BASH,
$ BASH_ARGV,$ BASH_COMMAND,$ BASH_SUBSHELL,BASH_EXECUTION_STRING …。如果
调用由sh(也如果源在一个sh),执行shell会看到
所有这些$ BASH_ *作为空的环境变量。同样,这可以使用
在脚本内发现这个条件和“做某事”…但不是
防止调用以下命令!
我现在假设…
> …脚本使用#!/ bin / bash作为它的第一行,
> …用户已将Bash设置为其shell并调用命令
下面的表从Bash和它是他们的登录shell,
> … sh可用,它是bash或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)
现在你可以把一个逻辑到你的文本脚本:
>如果$ 0不等于-bash,则执行退出$ SOMERETURNVALUE。
如果脚本通过sh myscript或bash myscript调用,那么它会
退出调用shell。如果它在当前shell中运行,它会
继续运行。 (警告:如果脚本有任何其他退出语句,
你当前的shell会被’杀死’…)
所以把它放在你的非可执行文件myscript.txt附近它的开始像一样
这可能做一些接近你的目标:
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