不是原创,综合了一下两篇文章
一 shell 的变量与shell执行方式,子shell
1.export 将一个变量变成环境变量
�栏�碚f,我��在��前 shell 中所定�x的�量,均�凫�"本地�量"(local variable),
只有��^ export 命令的"�出"�理,才能成�榄h境�量(environment variable):
$ A=B
$ export A
或
$ export A=B
��^ export �出�理之後,�量 A 就能成�橐���h境�量供其後的命令及子进程(包括子shell)使用。
要理解�@�� export ,事��上需要�� process 的角度�砝斫獠拍芡�亍�
首先,我��所�绦械娜魏纬淌剑�都是由父行程(parent process)所�a生出�淼囊��子行程(child process),
子行程在�Y束後,�⒎祷氐礁感谐倘ァ4艘滑F像在 Linux 系�y中被�Q�� fork 。
(�楹我�程�� fork 呢?嗯,��一下�D或�S比�^好理解... ^_^ )
��子行程被�a生的�r候,����母感谐棠茄e�@得一定的�Y源分配、及(更重要的是)�^承父行程的�h境�u
�我��回到上一章所�到的"�h境�量"吧:
* 所�^�h境�量其��就是那些���鹘o子行程的�量。
��味�言,"�z�餍�"就是�^分本地�量�c�h境�量的�Q定性指�恕�
然而,�倪z�鞯慕嵌�砜矗�我��也不�y�l�F�h境�量的另一��重要特徵:
* �h境�量只能�母感谐痰阶有谐�蜗蚶^承。�Q句��f:在子行程中的�h境如何�更,均不��影�父行程的�h境。
2 子shell
接下�恚�再�我��了解一下命令�_本(shell script)的概念。
所�^的 shell script �v起�砗芎��危�就是�⒛闫�r在 shell prompt 後所�入的多行 command line 依序��入一��文件去而已。
其中再加上一些�l件判�唷⒒�咏缑妗��颠\用、函�嫡{用等等技巧,得以� script 更加"�明"的�绦校�
但若撇�_�@些技巧不�,我��真的可以��蔚目闯� script 只不�^依次�绦蓄A先��好的命令行而已
再�Y合以上���概念(process + script),那���就不�y理解如下�@句�的意思了:
* 正常�碚f,��我���绦幸�� shell script �r,其��是先�a生一�� sub-shell 的子行程,然後 sub-shell 再去�a生命令行的子行程。
然�t,那�我��思考下面的例子:
a.sh脚本如下,里面调用b.sh
#!/bin/sh
echo "--start parent proc--"
echo $PWD
echo "--parent start child proc--"
sh b.sh
echo "--return to parent proc--"
echo $PWD
b.sh脚本如下
#!/bin/sh
echo $PWD
cd /home
echo $PWD
调用结果
[root@test 1029]# sh a.sh
--start parent proc--
/root/1029
--parent start child proc--
/root/1029
/home
--return to parent proc--
/root/1029
因�椋�一般我��跑的 shell script 是用 subshell 去�绦械摹�
�� process 的�^念�砜矗�是 parent process �a生一�� child process 去�绦校�
�� child �Y束後,��返回 parent ,但 parent 的�h境是不��因 child 的改�而改�的。
所�^的�h境元�岛芏啵�凡�e effective id, variable, workding dir 等等...
其中的 workding dir ($PWD) 正是�侵鞯囊��所在:
��用 subshell �砼� script 的�,sub shell 的 $PWD ��因�� cd 而�更,
但��返回 primary shell �r,$PWD 是不���更的。
3.shell执行方式(sh 脚本或source 脚本)
��你有了 fork 的概念之後,要理解 source 就不�y:
* 所�^ source 就是� script 在��前 shell ��绦小⒍�不是�a生一�� sub-shell ��绦小� 调用方式是 source script-file或者 . script-file
由於所有�绦薪Y果均於��前 shell �韧瓿桑�若 script 的�h境有所改�(包括export新的环境变量),��然也��改���前�h境了(脚本里面export的环境变量导入到当前环境)�u
例如单独执行b.sh
如果直接执行
[root@test 1029]# sh b.sh
/root/1029
/home
[root@test 1029]#
执行完后仍然在当前目录1029下
如果用source执行
[root@test 1029]# source b.sh
/root/1029
/home
[root@test home]#
执行完后就到目录/home里面去了
二 login shell�c non-login shell
1 概念
* login shell:取得 bash �r需要完整的登入流程的,就�Q�� login shell。�e例�碚f,你要由 tty1 ~ tty6 登入,需要�入使用者的�ぬ��c密�a,此�r取得的 bash 就�Q�椤� login shell 』�樱�
* non-login shell:取得 bash 介面的方法不需要重�}登入的�e�樱��e例�碚f,(1)你以 X window 登入 Linux 後, 再以 X 的�D形化介面��咏K端�C,此�r那���K端介面�K�]有需要再次的�入�ぬ��c密�a,那�� bash 的�h境就�Q�� non-login shell了。(2)你在原本的 bash �h境下再次下�_ bash �@��指令,同�拥囊�]有�入�ぬ�密�a, 那第二�� bash (子程序) 也是 non-login shell 。
2 读取的文件
�@���取得 bash 的情�r中,�x取的�O定�n�Y料�K不一�铀�致。 由於我��需要登入系�y,所以先�� login shell ���x取哪些�O定�n?一般�碚f,login shell 其��只���x取�@����O定�n:
1. /etc/profile:�@是系�y整�w的�O定,你最好不要修改�@���n案;
2. ~/.bash_profile 或 ~/.bash_login 或 ~/.profile:�凫妒褂谜��人�O定,你要改自己的�Y料,就��入�@�e!
2.1 /etc/profile (login shell 才���x)
�@���n案�O定的��抵饕�有:
* PATH:��依�� UID �Q定 PATH ��狄�不要含有 sbin 的系�y指令目�;
* MAIL:依���ぬ��O定好使用者的 mailbox 到 /var/spool/mail/�ぬ�名;
* USER:根��使用者的�ぬ��O定此一���热荩�
* HOSTNAME:依��主�C的 hostname 指令�Q定此一���热荩�
* HISTSIZE:�v史命令���P�怠�CentOS 5.x �O定�� 1000 ;
/etc/profile 可不止��做�@些事而已,他���去呼叫外部的�O定�Y料喔!在 CentOS 5.x �A�O的情�r下, 底下�@些�Y料��依序的被呼叫�M�恚�
/etc/inputrc
/etc/profile.d/*.sh
/etc/sysconfig/i18n
2.2 ~/.bash_profile (login shell 才���x)
bash 在�x完了整�w�h境�O定的 /etc/profile �K藉此呼叫其他�O定�n後,接下��t是���x取使用者的��人�O定�n。 在 login shell 的 bash �h境中,所�x取的��人偏好�O定�n其��主要有三��,依序分�e是:
1. ~/.bash_profile
2. ~/.bash_login
3. ~/.profile
其�� bash 的 login shell �O定只���x取上面三���n案的其中一��, 而�x取的�序�t是依照上面的�序。也就是�f,如果 ~/.bash_profile 存在,那�N其他����n案不�有�o存在,都不��被�x取。
2.3 ~/.bashrc (non-login shell ���x)
[root@www ~]# cat ~/.bashrc
# .bashrc
# User specific aliases and functions
alias rm='rm -i' <==使用者的��人�O定
alias cp='cp -i'
alias mv='mv -i'
# Source global definitions
if [ -f /etc/bashrc ]; then <==整�w的�h境�O定
. /etc/bashrc
fi
常见问题
如果我们在/etc/profile里面定义了JAVA_HOME,然后写了java的启动脚本,常常会发现直接执行脚本可以,但是放入到crontab里面就不行(因为crontab里面的是在non-login shell下执行的,不会读取/etc/profile文件,自然找不到$JAVA_HOME
这个时候crontab这么写
su - root 脚本
好久没更新
随便写写
主要是体验一下新模板