solaris移植到linux的大坑:bash和sh中环境变量继承的差异

时间:2021-03-10 16:42:56

一、问题的引出

项目中脚本A 、B,A调用B,
其中A中所有命令均使用绝对路径,B中直接使用
在solaris上工作正常,移植到linux中报错:

/syscom/lm/linux//backupgen: line 60: mkdir: command not found
/syscom/lm/linux//backupgen: line 61: cd: /syscom//tmp/syscom_dir: No such file or directory
/syscom/lm/linux//backupgen: line 62: mkdir: command not found

没有找到cd、mkidr等命令,很明显是PATH变量设置错误了。
很快定位到问题点,在A中设置了非法的PATH值:

PATH=/syscom/tmp

那为何在solaris上就没有报错了?

二、bash中环境变量的继承关系

该脚本使用的解释器是/bin/sh,在一般的理解中,bash和sh完全一样。

[jud@syscom]$ls -l /bin/sh
lrwxrwxrwx. 1 root root 4 Mar 18 2014 /bin/sh -> bash

在linux中sh是bash的链接,已经没有sh了。

测试bash中变量继承关系:

[jud@~]$TEST=a                    #设置自定义变量TEST值为a
[jud@~]$echo $TEST
a
[jud@~]$bash #进入子bash
[jud@~]$echo $TEST #打印TEST变量,值为空

[jud@~]$ echo $PATH #打印PATH变量的值
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/syscom/bin:/syscom/lm/linux:.
[jud@~]$ PATH=/tmp #设定PATH的值
[jud@~]$ echo $PATH
/tmp
[jud@~]$ bash #进入子bash,无法使用bash命令
-bash: bash: command not found
[jud@~]$ /bin/bash #必须用绝对路径才可以
bash: id: command not found
bash: id: command not found
[jud@~]$ echo $PATH #子bash继承了父bash的环境变量
/tmp

如果通过export命令将自定义变量 TEST变更为 环境变量

[syscom@sysbase0-0 ~]$ export TEST=a
[syscom@sysbase0-0 ~]$ bash
[syscom@sysbase0-0 ~]$ echo $TEST
a

从以上的举例中可以看出来,bash中自定义变量是不能继承的,环境变量是继承的。

sh中环境变量继承关系

在古老的solaris上仍然使用着sh

> ls -l /sbin/sh
-r-xr-xr-x 1 root root 95492 9222010年 /sbin/sh
> ls -l /usr/bin/bash
-r-xr-xr-x 1 root bin 795204 122421:58 /usr/bin/bash

可见在solaris上bash与sh是两个不同的shell!
测试sh中的变量继承关系:

> sh
$ TEST=a #设置自定义变量TEST值为a
$ echo $TEST
a
$ sh #进入子sh
$ echo $TEST #打印TEST变量,值为空

$ echo $PATH #打印PATH变量的值
/usr/local/PGRUV05L23R1000_sol:.:/export/home/fnstli:/export/home/fnstli/bin:/usr/sbin:/usr/bin:/opt/SUNWspro/bin:/usr/ucb:/usr/etc:/usr/local/bin:/usr/ccs/bin:/usr/include:/etc/opt/FSUNiconv/bin:/usr/openwin/bin:/usr/X/bin:/usr/bin/X11:/usr/xwin/bin:/syscom-E11/lm/solaris:/syscom/tool:/syscom-E11/bin:/usr/sfw/bin:/opt/netbeans-5.5.1/bin:/usr/jdk/jdk1.5.0_16/bin:/usr/sfw/bin
$ PATH=/tmp #设定PATH的值
$ echo $PATH
/tmp
$ /sbin/sh #进入子sh
$ echo $PATH #子sh中的$PATH没有继承父sh的值!
/usr/local/PGRUV05L23R1000_sol:.:/export/home/fnstli:/export/home/fnstli/bin:/usr/sbin:/usr/bin:/opt/SUNWspro/bin:/usr/ucb:/usr/etc:/usr/local/bin:/usr/ccs/bin:/usr/include:/etc/opt/FSUNiconv/bin:/usr/openwin/bin:/usr/X/bin:/usr/bin/X11:/usr/xwin/bin:/syscom-E11/lm/solaris:/syscom/tool:/syscom-E11/bin:/usr/sfw/bin:/opt/netbeans-5.5.1/bin:/usr/jdk/jdk1.5.0_16/bin:/usr/sfw/bin

从以上的举例中可以看出来,sh中自定义变量是不能继承的,环境变量同样不能被继承!

总结

环境变量在sh和bash的继承规则并不相同。在solaris的脚本向linux平台移植时,需要特别注意solaris大多使用sh解释运行脚本!