给自已定了目标之后,就不要轻易放弃,给自已个机会,认认真真的做好它

bash

上一篇 / 下一篇  2008-08-07 14:20:17 / 个人分类:脚本

bash- [Ubuntu]

Tag:Linuxbash

版权声明转载时请以超链接形式标明文章原始出处和作者信息及本声明51Testing软件测试网j0{V/r-{]G'f I8p5h
http://kimva.blogbus.com/logs/19988697.html51Testing软件测试网e*cT~e8Gg}m
51Testing软件测试网^,{:kNb

9L3}Q3gr]z$hb0GNU/Linux支持多种版本的shell. 但默认的是bash. /etc/shells文件列出了本机linux系统支持的shell类型. /etc/passwd中列出了用户默认的登录shell.
!g4ql.W)bY2P0
[n EkGi0从当前shell转换到另一种shell: 直接在命令行输入对应的shell程序名.如:51Testing软件测试网6[ Q&V s1~]2A){;O
$sh51Testing软件测试网 AQ"mDG
sh-3.00$
-p.|~@l K{(JY0提示符变了, 要退回到之前的bash, 可输入exit或使用C-d组合键.
,G.xrzOqB|0
!Q ^|8]!\ [1C&Q0bash的特色51Testing软件测试网w(iI4j-RH f

1, 命令行参数: sh只能传送单字符参数(可通过内置的set命令配置), bash还可以传送字符串参数.
[[-T-G0F?MAE02, 启动配置文件: bash启动时, 依次读取启动文件, 这样可以在bash启动时完成一些默认的配置工作. (关于bash配置文件, 后面再讨论).51Testing软件测试网E;wI NO:C
3, bash是交互性shell.
p"n7f6k xC;f:D?04, 条件表达式.51Testing软件测试网H;@0Iu@#Tx g
5, shell算术.
X/u)]/A_,M/T1]"d06, 别名.51Testing软件测试网G*YnH-Zi \-M0Z8x8E W
7, 数组51Testing软件测试网4XI4[ PDbIJ)A&{VG
8, 目录栈.
;A$N&]yk/i-_w+m09, 受限版的bash: rbash.
Z [ W$C7dVqUze051Testing软件测试网OI R6G'X,ey
bash命令的执行
H8X5W"s&?,cvQ Es9uV0

bash能够识别要执行内容的类型: 是系统中的可执行程序, 还是bash的内置命令, 或者是一个bash脚本? 根据这些类型, bash的执行方式有所不同:
{'Lt6E5s&OS0
:kVFlD3p0G#wBa6@01,可执行程序: 遵循fork-exec形式, 它fork出一个子bash进程, 父bash和子bash仅进程号不同. 注意这种情况下, 父进程等待子进程执行, 子bash执行完毕退出后, 父bash重新执行. 程序对子bash的环境做出的更改不会影响父bash.
(a i#f` Sw7P&Ps}1M0
i Y)o ?,QZdS02,bash内嵌命令: bash直接执行命令, 不新生成一个进程.
g vu?5wv8s-\051Testing软件测试网|*D{,J:Ch
3,bash脚本: 分两种情况:
@V(Rr$p&?0(1) 如果直接执行脚本, 比如: $./foo.sh, 此情况与执行可执行程序相同, 生成的子bash进程一次从脚本读取一行命令来执行, 如同用户从键盘输入命令.
+wX)Xx~0
3G+Pf[y-j*X%I8W{0(2) 如果执行 $source ./foo.sh, 这相当于执行bash的内嵌命令, 也可以起到执行脚本命令的作用, 但不生成新的bash. 所以如果需要在脚本中更改bash环境变量的话, 要用source命令! 直接运行脚本只能更改fork出的子bash的环境变量, 运行结束后, 子bash退出, 父bash的环境变量不受影响.51Testing软件测试网8p]/Qk7Ok2dA
51Testing软件测试网5Z'v%O#H9KEj!J-iC

F7lE3}+`%y3o0编写bash脚本
:?1}V}}0@ cp0

1, 推荐使用能够显示bash语法高亮的编辑器, 比如emacs, gedit, vim...51Testing软件测试网*pEAg+X

)^$e+f^OEW?.}4uN q02, 自己编写的脚本怎样命名, 放在什么地方?51Testing软件测试网d y"K;x+ry6p(}/rN6Y*],w
命名: 为了避免自己写的脚本与系统命令重名, 建议shell脚本以.sh结尾. 但自己写的脚本还是可能与系统自带的脚本重名, 建议命名前通过$which scrīptname.sh(或者whereis, locate)来查看.51Testing软件测试网3xR`2`zu3~-_q:z

$N'i"t]&EN0位置: 可以将自己写的脚本放在一个合适的目录中, 比如~/scrīpt. 
*u/Uc;{y?J051Testing软件测试网n'P jvc5nf/a
Unix/Linux不利用文件扩展名来判断文件类型. 要想知道文件类型, 可使用file命令.
"nK B tm'Z0

bX;X:Q"@GVT03, 如何执行脚本?51Testing软件测试网2u5f B&W#IK(y\m
(1) 脚本可以像命令一样被执行:51Testing软件测试网3KN5c`}-j
$/bin/bash file.sh(不需要file.sh的可执行权限)
?j@,[$\0
/k5a+L3^5t5dB6h0如果你懒得输入/bin/bash, 可以采取下面的两种方法:51Testing软件测试网 \ I9Qe2Tv'd;Y
如果脚本被集中放置在~/scrīpt目录, 可以将该目录添加到PATH中再直接调用
&vi-_S0CU)C0$export PATH="$PATH:~/scrīpt"
^ S,?9j6I$r!j"U0由于脚本所在的目录在PATH环境变量中, 所以可直接运行: $ file.sh(需要file.sh有可执行权限)51Testing软件测试网'}:^iM"XA4{
51Testing软件测试网9s4sQMzPC5T9y&s
如果想执行当前目录的脚本, 可以运行$./scrīptname.sh  (需要file.sh有可执行权限)
e @I _G]0方法(1)使bash新生成一个子bash来执行, 在此情况下, 脚本对环境变量的更改只对子bash有效.并且在执行脚本文件之前必须更改权限(指明shell路径时不用), 让脚本具有相应的执行权限.51Testing软件测试网?:_4]&VFy c5Q'O
 51Testing软件测试网3a2o:}fmQ` Li
(2) 可使用source命令来直接执行脚本(可用'.'来代替source). 它与上面的方法有两点区别:51Testing软件测试网#ib P|/g&E
1, 脚本文件不需要执行权限.
:U)VTP7}u!jc02, 就在当前bash中执行, bash不会新fork一个子bash来执行它, 所以脚本对环境变量的更改会影响到当前bash.
{K,QAUmPx:n0
*R"a}+x'|WE5L0
推荐使用./file.sh在当前目录执行脚本, 这样可以避免误调系统其他位置的重名脚本. 如果需要更改当前shell的环境变量, 则使用source命令. 不推荐修改环境变量: 这会造成系统的安全隐患.
Jq6rGm0

%J t'Q&{:e q,`0当你确认脚本运行无误, 而且需要经常执行它时, 可将它copy到合适的系统执行目录, 比如/usr/bin, /usr/local/bin 或者~/bin(需修改PATH)中. 然后向调用命令一样执行它.
#N:S)YI2S/q2h051Testing软件测试网$cO$t l g jcq3U
51Testing软件测试网)iL$ct,@
脚本结构51Testing软件测试网e)Q}J8X(}8N6TC,r7_'A

脚本开头第一行指定运行脚本的shell, 一般指定为bash:
7e;s-O'FG:VC1qL0#!/bin/bash51Testing软件测试网f+w&}t%Dwj9e*z O
51Testing软件测试网qq SLv@,Ur)u
bash脚本中的注释以'#'开头, #之后到行尾的内容为注释, 在执行时会被bash忽略. (脚本中不能再在同一行的注释之后添加命令, #之后到行尾的内容都会被bash忽略!)  但脚本开头的#!是个例外!
&u8pYyi A'f0

q}*~4o&I S p/m&q0在脚本结尾的最后一行, 一般包含一个 "exit 0" 语句(0表示执行成功). 它返回一个值. 注意: 在交互式bash中, 这条命令没什么用处. 当它所在的脚本被被的脚本调用时, 就能确定被调用的脚本是否正确执行了. 你的脚本在将来可能被别的脚本所调用, 所以最好在脚本末尾包含这条语句. 这也是编写可重用脚本的一个好习惯.51Testing软件测试网IuFc pGi4o8s2T

Rb:e4]#^-@8FV0
$PHt)spUQo-gb:K0调试脚本
/Scdg*~5[Lq9I0

调试整个脚本51Testing软件测试网U"MJ4{!au#H?

"S b#hEB0
最通用的方法是新调用一个bash, 以调试选项"-x"来执行脚本: $bash -x scrīptname.sh51Testing软件测试网7tH2S0Ko!D;jx aC
这种情况下, 新bash在显示每个语句生成的结果之前打印出该语句(以+开头), 这样易于我们对比语句和执行结果.
w#f&}7VUQ,L!F051Testing软件测试网rY$_ fz#r
调试脚本的部分内容51Testing软件测试网+a0xOJw T

'e"|D+SZXY`0
只需在脚本中你想调试的语句之前添加: set -x, 然后在结尾添加: set +x. 可以把这两条语句当作"调试开关", 在脚本中多次调用.
a4Qm(D|0^f0
M,o0|'z-B.u%q2h0调试选项归纳如下:51Testing软件测试网KdMfY!x6qZ
Short notation    Long notation    Result51Testing软件测试网m1O!b^}%ht1u X
set -f         set -o noglob    Disable file name generation using metacharacters (globbing).
@+X$} W fqR0set -v         set -o verbose    Prints shell input lines as they are read.51Testing软件测试网5E1R(h,dvn9h q
set -x         set -o xtrace    Print command traces before executing command.51Testing软件测试网"^m(IS/] Q-vJ2k

YfM_ i0注意, -为打开启用调试,+为关闭调试,这容易混淆.
]5r4XUjA,~.x ?J051Testing软件测试网f+OKj~\ s
这些选项不光可以添加到脚本文件中, 还可以直接在命令行中指定. 
+] v9](R"m%A/{0e.g:51Testing软件测试网m9D {F{I,n*wmD L
$set -x
(L ?KP"^|*o0$ls51Testing软件测试网Lm? Bzi;yv
看看结果吧 :)51Testing软件测试网sdR:a#g$O

;u3r'`l:\i051Testing软件测试网\4n4T#@e$]W
bash环境51Testing软件测试网 R-U b.D%F[DJ0Y

启动配置文件的读取51Testing软件测试网$X O!mwgib
51Testing软件测试网4Bm-xM h)K|;E"Kg [
首先要理解: 交互式bash和非交互式bash(interactive& non-interactive)51Testing软件测试网 CAO#]w _V R,rg
51Testing软件测试网&C.pwG;p6[
交互式shell: 用户输入命令给shell执行, shell将执行的结果通过输出反馈给用户. 51Testing软件测试网wMW-s d~ e
51Testing软件测试网lpN9C5H4S
非交互式shell: 命令(脚本)在后台执行, 执行过程中不读取用户输入, 也不反馈执行信息.(执行完毕后可能会显示一些信息).
:w)^W+NB%r M051Testing软件测试网3e,y%d4S~IzBE1U k%s
如何判断某个shell是不是交互式的呢? 可以运行 $echo &-, 若输出中还有小写字母'i', 则是交互式shell. 一般而言, terminal或console都是交互式shell, 而shell脚本在执行时执行它的shell就是非交互式的.
51Testing软件测试网v0k~S ?D J-f
交互式bash还有两种调用方式: login和non-login.51Testing软件测试网bo[ g"Q,Pu}
51Testing软件测试网 `EV/?XK-g.D z6{8y
login: 我们在文本模式下登录console时, bash提示输入用户名和密码, 此时的bash就是login的.51Testing软件测试网Ak{9mNp~u;uB

5av|2V2M0non-login: 在图形模式下, 打开一个 terminal, 不需要输入用户明或密码, 此时调用的bash就是non-login的.51Testing软件测试网#A9e:E r0P-jL7x QG
51Testing软件测试网^ Se}9F ]y {7m'u
根据login和non-login的区别, bash在启动时读取不同的配置文件:
2Yq-z,^Ol3G*L0
._T U;{\[0login:51Testing软件测试网#a-j2r9p~r/N
1, 读取/etc/profile: 它是所有用户, 所有shell的启动配置文件. /etc/profile还会读取/etc/bash.bashrc, 它是所有用户的bash启动配置文件.
zR0H~R;o\051Testing软件测试网pp2zkGL$PH
2, 读取~/.bash_profile, 若它不存在, 则读取~/.bash_login 同样, 若前两者不存在, 读取~/.profile. 
,P2t^.P Y051Testing软件测试网b6MMkf$Z&Vd'x
3, 在logout时读取~/.bash_logout51Testing软件测试网fD'm"S"s`6R"wu

a&w}rAe9B7eT2B0non-login:51Testing软件测试网.C$}A,]%xf3X
读取~/.bashrc.
Mae+c$xni051Testing软件测试网Imv(K ~2~
可以自行在上述的配置文件的末尾添加echo语句, 这样在console中登录或者打开一个终端时就能显示配置文件的读取信息. 上面的总结基于Ubuntu, 各发行版可能情况不同.51Testing软件测试网0t%]7l?$s
51Testing软件测试网5r3^"?6n!mz m.]
non-interactive:
5`K)H$E+CPd0读取的文件由BASH_ENV定义. 这些文件要用全路径, 因为无法用PATH变量来搜寻这些文件.51Testing软件测试网4~8\2{%Cc!E
51Testing软件测试网$s1P {u)g,Y6Qh
51Testing软件测试网"a w3F%X3xAs
bash的初始化文件51Testing软件测试网%~x0We*s NmO q

一, 针对整个系统所有用户的login配置文件.
|3[*@7jz9J+n0
N-Hr` ?+K^0
1, 针对整个系统的所有用户, 所有shell的配置文件 /etc/profile51Testing软件测试网"u?M7_5NO$}
# System wide environment and startup programs, for login setup
/GTE9}coQQ051Testing软件测试网p+w%zD/km%FhO}
注意: 该配置文件被交互式login shell读取, 以bash为例, 在图形模式下打开terminal时是交互式non-login的, 所以不会读取/etc/profile: 运行 $bash, 不会读取/etc/profile. 但如果以 $bash --login, 则会读取.51Testing软件测试网Q/u g)^R`O
51Testing软件测试网X5Z V$PS!ok
在字符界面下, 最初登录时会读取/etc/profile. 登录后的情形等同于图形界面的terminal.
LQ @0ap^)z c051Testing软件测试网EiJi9X;T&S2n
2, 针对整个系统所有用户, bash的配置文件/etc/bash.bashrc51Testing软件测试网LkB5\:FF
它一般会被/etc/profile读取以配置bash环境.51Testing软件测试网f'l(SyTdw
51Testing软件测试网g6I"fx _+K2uXZUE
二, 针对单个用户的login配置文件
/]HCaJy3f0这些配置文件默认位于用户的home目录, 以.开头, 是隐藏文件. 如果它们不存在, 可以创建它们.
tL(G$B2s~t8T:]-D051Testing软件测试网,y:GE"n%X/}3H
1, ~/.bash_profile51Testing软件测试网&J*_^R/Z$M'B@
This is the preferred configuration file for configuring user environments individually. In this file, users can add extra configuration options or change default settings.
_'ZOD3`g0
`"W-S:~5A8_/S d*h0与/etc/profile相同, ~/.bash_profile在交互式, login情况下被读取.
| n;Z(IPf0如果~/.bash_profile不存在, 则读取~/.bash_login, 若~/.bash_login也不存在, 则读取~/.profile.
V]Fk`(v.d2_ W051Testing软件测试网yc vW}A@5i
三, 针对单个用户的login-out配置文件51Testing软件测试网-k^+c&bG3dQ
在logout时候, bash读取~/.bash_logout文件.51Testing软件测试网2L,`GJ Z
51Testing软件测试网#\guy^o.C
四, 针对单个用户的non-login配置文件51Testing软件测试网W3v'K U5o4e:}(u
~/.bashrc
[W/s*n }#ODd0在图形模式下, non-login bash更为广泛地存在: 打开一个terminal一般不会读取/etc/profile或~/.bash_profile文件, 因为图形模式下打开终端时是non-login的. 这种情况下通过~/.bashrc来配置.
iU/h k5]$df h/Py0~/.bashrc是否会被读取的情况等同于/etc/profile和~/.bash_profile.
eDM/s!Bd2z&?5c0
aXG NX(l&fQ"L0
这样, 我们就知道在定制bash环境时, 如何针对自己的需要修改这些配置文件了:
:} q5DOW,I051Testing软件测试网9j ~$EutKu#[
login情形下, 针对所有用户的定制: /etc/bash.bashrc;  针对单个单个用户的定制: 修改~/.bash_profile51Testing软件测试网8k0b4q4u-zl

&nr:] E%`[q0non-login情形下: 针对所有用户的定制: /etc/bash.bashrc; 针对单个用户的定制:  修改~/.bashrc
(W \$H_%o@,z0
5?!qi!U2[0注意: /etc/bash.bashrc会被login或non-login的bash读取!
M3^Cb3qS0

xKl(s/d0对这出配置文件进行修改后, 可以重登录, 或者新开一个bash, 或者使用source命令来使它们生效.51Testing软件测试网l%u8^9P IW,W6]
51Testing软件测试网j A:R#{S:V MJ
有时候可能记不清到底是哪些配置文件被读取, 可在上述的文件末尾添加一条echo语句, 显示它是否被调用. 然后打开一个terminal或者进入console看看, 就知道哪些配置文件被调用, 以及它们的调用顺序.51Testing软件测试网!t'n3Z\1x%^$~7K
51Testing软件测试网] _#a \Kfyc2q LN
原文引自:http://lnote.blogbus.com/logs/10075261.html

TAG: bash 脚本

 

评分:0

我来说两句

Open Toolbar