Bash tips
上一篇 / 下一篇 2008-03-07 16:02:54 / 个人分类:LAMP
Contents
[hide]- 1Introduction
- 2Using quotes
- 3Return values
- 4Conditions
- 5Negations
- 6Loops
- 7Get your IP address
- 8Some counting examples
- 9Combining multiple conditions of if statements
- 10Conditional execution
- 11Functions
- 12Renaming a set of files
- 13Converting several wav files to mp3
- 14Full file name
- 15Resolving a link
- 16Viewing a file according to its type
- 17Finding the 50 largest directories
- 18Auto-generating a shebang line
- 19Creating an audio CD from .mp3 files
- 20Portable Indirection
- 21Matching Curly Brackets
- 22rpminfo
- 23Copy files/dirs and leave the symbol links as they are
[edit]Introduction
$?8O5R&?6{y)moL0If you type in a rather long and complexcommandat thecommand line, you might want to save that command in atext file, so you can execute it later without having to type the whole long thing in again. If you add a line to the beginning of that file, like "#!/bin/bash" (a so-called "shebang" line), and then make the file executable with thechmodcommand, you've just created a shell script.木铎校园 BBS 社区"z2Oc]*t\2h m
W'ErL!q*A @A,OQ0Here's an example shell script:木铎校园 BBS 社区%Gc!qyL
#!/bin/bash木铎校园 BBS 社区*W%X$Lq&pd|6W#s(q
# Any line that starts with a hash, besides the shebang line, is a comment.
Z!K{2d;l#B${,X0echo "Hello world!"木铎校园 BBS 社区(}4W!}h~ oHD
5wH ^Gp q u0You run theshell scriptjust like any otherexecutable. Some folks create abindirectory in their home directory within which to place their scripts. Others drop them in/usr/local/bin.
/A&s/rPY]d"GD0木铎校园 BBS 社区M\YM+GSome key points to keep in mind about shell scripts:木铎校园 BBS 社区#WZ#rEAz9Ky"q
- They execute their commands, line by line, just as if you'd typed them in yourself at the command line.
- The commands in the script run in a subshell of the shell from which you executed the script.
- If you want the script to affect yourpresent working directoryorenvironment variables, source it with. scriptname.
- Don't put spaces around equal signs.
$?eHAy9|moUq0You could check out thebashpage and you'll also find lots of info in theAdvanced Bash-Scripting Guide.木铎校园 BBS 社区6@-V I'c|0dQ Ps
木铎校园 BBS 社区~;Zq\r5p_u&AhEnjoy!木铎校园 BBS 社区!B:x,U5B,D]w
[edit]Using quotes
,} G$`OX]1r2a9R0Quotation marks, either double quotes (") or single quotes ('), are often needed in shell scripts to pass arguments that have spaces or other special characters. The two quotes have slightly different meanings. Single quotes protect the exact text they enclose.
(lEh]%Wl&D"\,i0木铎校园 BBS 社区t%z+g8v}*]Inside double quotes, the dollar sign ($) is still special, so shell variables and other $ expressions are interpreted, as is the backquote (`) used for command substitution. Lastly, the backslash (\) is special in double quotes, so be cautious. Some examples and the shell output of each:
_7zZ1vB$N w0NDt0$ echo 'The location of the shell is stored in $BASH'
w L!bQi4m0The location of the shell is stored in $BASH
~$|]&v&vIU_0$ echo "The location of the shell is $BASH"
;e*C1gEPm0The location of the shell is /bin/bash木铎校园 BBS 社区Mc,bEu\,j
$ echo '\\'木铎校园 BBS 社区'vtj8q9g$@-o6c
\\
A(L D5V9^[(Y+l0$ echo "\\"木铎校园 BBS 社区z'sp5G;s.l%VL
\木铎校园 BBS 社区y2u NA5x
[edit]Return values
木铎校园 BBS 社区 vWgqr(e;{qThe return value, also known as error code, delivers the exiting state of the most recently executed program. It is defined to be 0 in case no error happened. It is stored in the variable $?:木铎校园 BBS 社区Y'[4\Jz$KK r
scorpio:~ # echo "hello world"木铎校园 BBS 社区U9mZ{?#[ QS
hello world
A;ul0y g gK0S5]wO0scorpio:~ # echo $?
~8O0wHy$J00
U+]3Is]?d,q]0scorpio:~ # ls /doesNotExist
!TS@\Y;[#e0/bin/ls: /doesNotExist: No such file or directory
Azl Z N7Zb#Dv0scorpio:~ # echo $?
7SVd{E&J4K[02
3u`-^1?6eE-kwvb0
~8id|;p/c0The [ ] operators deliver 0 if they contain a true expression, 1 if they contain a false expression:木铎校园 BBS 社区 f"HxVXJ7E4E
scorpio:~ # [ 5 = 5 ]
v.w`l0`%|t Lz0scorpio:~ # echo $?
f\3Z_^_L}3?1O6c00木铎校园 BBS 社区FJ2U5l?#[M7LASo
scorpio:~ # [ 5 = 6 ]木铎校园 BBS 社区.J/F? hbb l~(m
scorpio:~ # echo $?木铎校园 BBS 社区8[3s%N^ K
1
!Os4X\9nv2z2T0scorpio:~ #木铎校园 BBS 社区5@k.H+on6[C
p!Xft Id0@0Here, [ is acommand. A command requires a blank behind it - thus the following error is very common:木铎校园 BBS 社区Wtb2T!`gGsQ L$c3I
scorpio:~ # [5 = 6]木铎校园 BBS 社区IkV.fRB#_f3v
H,w5I/l~D,u0bash: [5: command not found木铎校园 BBS 社区 Sf,Bc [ bX#l
Also the ] requires a blank in front of it:
c_\2L'wu*q&E5JG0scorpio:~ # [ 5 = 6]木铎校园 BBS 社区:f ^r*P V+U(vGy6Af
bash: [: missing `]'木铎校园 BBS 社区sb%|)my
~9h6?}2A-q0The "=" sign requires a blank in front of it and after it. Otherwise, the bash only sees "something" within the brackets, and that is true (0), while "nothing" is false (1):
4`?-}6i6G$ay0scorpio:~ # [ aoei ]
j8x4\m.e0scorpio:~ # echo $?木铎校园 BBS 社区ex'@2jQ*cX
0木铎校园 BBS 社区LUQ TvZ
scorpio:~ # [ 5=5 ]
:eK|;_[B-[-c0scorpio:~ # echo $?
"EQ!~6B(Gs1x00
.`q4hfw#T3g0scorpio:~ # [ ]
9V#Z!|b ~p1ig0scorpio:~ # echo $?木铎校园 BBS 社区(i;e}-X/W/o(c[:N
1
,\IXO9F*w!@0scorpio:~ # true木铎校园 BBS 社区%Y4|*h.SU*E
scorpio:~ # echo $?木铎校园 BBS 社区"Ypa-W[(hR
0
2S1Z)tx}By?X[(l0scorpio:~ # false
;zl/DWLE1C(e1F0scorpio:~ # echo $?
'}3ybc8r.^jOC01木铎校园 BBS 社区~-@"~Q7C
2r9Q8j c]&} R8s0You can hand over your own error codes with the command exit. This command will exit from the current process. As the ( ) signs spawn out an own process, you can do the following:
$j$a(X'y8aT0scorpio:~ # (exit 5); echo $?木铎校园 BBS 社区5cv^+o$a#K
5木铎校园 BBS 社区4nfM0y hsNO*fvd
[edit]Conditions
木铎校园 BBS 社区sc#YE(k/t?!KXifae kConditions are handled with theifcommand, using the form if <expression> then command1 else command2 fi "fi" as the reverse of "if", closes the loop. bash allows you to substitute newlines with ";", so the following form is also legal: if <expression>; then command1; else command2; fi Example:木铎校园 BBS 社区j2]5D3@;g
scorpio:~ # if true; then echo "yes"; else echo "no"; fi木铎校园 BBS 社区2aTi:EUJ'Ce
.SRB)v5`-Fo0yes木铎校园 BBS 社区/p)~l$y(o q]8ALVI6@
scorpio:~ # if false; then echo "yes"; else echo "no"; fi
PjuD-W t-G?8Z0no
N4FW3p [0
You can omit the else-branch:
_{}lqF!w*O0scorpio:~ # if [ 5 = 5 ]; then echo "five is five"; fi
3?{Z'a-F"m0five is five
\S+} AaFXV0scorpio:~ # export name=Thorsten木铎校园 BBS 社区 m FB7z4sy ^&f R#@g8M
scorpio:~ # if [ $name = Thorsten ]; then echo "it's you"; fi
;f${9?jnj5j0it's you
W3hajX"f0
TDEPT o R L!a!Ee0In this case, bash replaces $name with its content. That means, we get an error if $name is empty:木铎校园 BBS 社区p Yu OTcKlds
scorpio:~ # export name=木铎校园 BBS 社区)IxL~ ro
k:u*vZ1]%t4T.X4r(Z0scorpio:~ # if [ $name = Thorsten ]; then echo "it's you"; fi木铎校园 BBS 社区v[]A\#m)g
bash: [: =: unary operator expected
;?Fd%j'{)K;xJeF0scorpio:~ # if [ = Thorsten ]; then echo "it's you"; fi
g2W T4av.x#ap0bash: [: =: unary operator expected
_4Go6P6f4p9dJ0
To overcome this problem, one can add an "x" to the left and to the right:
hY;}/g Y1c1ng-s0scorpio:~ # export name=Thorsten
7l;nX.oE^]RG0scorpio:~ # if [ x$name = xThorsten ]; then echo "it's you"; fi木铎校园 BBS 社区 q.J.{-H \
it's you
n;[ X};JPTCA&D0scorpio:~ # export name=
N:h0k.a4V:a?Wv0scorpio:~ # if [ x$name = xThorsten ]; then echo "it's you"; fi木铎校园 BBS 社区.m,gkSOo[2~:m+Q
scorpio:~ #
d:q2e$_7p+e?0
[edit]Negations
木铎校园 BBS 社区?6hR+G%G i+B6QWYou can invert true/false values with the ! operator:
etXJ];t:j;d0$ ! true木铎校园 BBS 社区Ak9i%?.KNo(O
+nJXG%| t*c0$ echo $?木铎校园 BBS 社区f_jg2W(i$Q6k'mKb
1木铎校园 BBS 社区 H8Hw6CY _k&q
That helps you if you want to do "not"-statements:
Ur0e,e!S8e8y0if !grep"network error" /var/log/messages
^1i+MHMg?0thenecho"There is no network error mentioned in the syslog"
a.OIER{GQg0fi
