Bash tips

上一篇 / 下一篇  2008-03-07 16:02:54 / 个人分类:LAMP

Contents

[hide]

[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~ o HD

5wH ^ G p 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+G

Some key points to keep in mind about shell scripts:木铎校园 BBS 社区#WZ#rEAz9K y"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@-VI'c|0dQ Ps

木铎校园 BBS 社区~;Zq \r5p_u&Ah

Enjoy!木铎校园 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!bQ i4m0The 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,bE u\,j
$ echo '\\'木铎校园 BBS 社区'vtj8q9g$@-o6c
\\
A(L D5V9^[(Y+l0$ echo "\\"木铎校园 BBS 社区z'sp5G;s.l%VL
\木铎校园 BBS 社区y2uNA5x

[edit]Return values

木铎校园 BBS 社区 vWgqr(e;{q

The 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$KKr

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 ZN7Zb#Dv0scorpio:~ # echo $?
7SVd{E&J4K[02
3u`-^1?6eE-kwv b0

~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!`g GsQ L$c3I

scorpio:~ # [5 = 6]
H,w5I/l~D,u0bash: [5: command not found木铎校园 BBS 社区Sf,Bc [ bX#l
木铎校园 BBS 社区IkV.fRB#_f3v

Also the ] requires a blank in front of it:

c_\2L'wu*q&E5JG0
scorpio:~ # [ 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$ay0
scorpio:~ # [ 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/DW LE1C(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'y8aT0
scorpio:~ # (exit 5); echo $?木铎校园 BBS 社区5cv^+o$a#K
5木铎校园 BBS 社区4nfM0y hs NO*fvd

[edit]Conditions

木铎校园 BBS 社区sc#YE(k/t?!KXifae k

Conditions 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
.SRB)v5`-Fo0yes木铎校园 BBS 社区/p)~ l$y(o q]8ALVI6@
scorpio:~ # if false; then echo "yes"; else echo "no"; fi
Pju D-W t-G ?8Z0no
N4FW3p[0
木铎校园 BBS 社区2aTi:EUJ'Ce

You can omit the else-branch:

_{}lqF!w*O0
scorpio:~ # 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
W3h ajX"f0

TDEPTo 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=
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
g2WT4av.x#ap0bash: [: =: unary operator expected
_4Go6P6f4p9dJ0
木铎校园 BBS 社区)Ix L~ro

To overcome this problem, one can add an "x" to the left and to the right:

hY;}/g Y1c1ng-s0
scorpio:~ # 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,g kS Oo[2~:m+Q
scorpio:~ #
d:q2e$_7p+e?0

[edit]Negations

木铎校园 BBS 社区?6hR+G%Gi+B6QW

You can invert true/false values with the ! operator:

etXJ];t:j;d0
$ ! true
+nJXG%| t*c0$ echo $?木铎校园 BBS 社区f_jg2W(i$Q6k'm Kb
1木铎校园 BBS 社区 H8Hw6CY _k&q
木铎校园 BBS 社区Ak9i%?.KNo(O

That helps you if you want to do "not"-statements:

Ur0e,e!S8e8y0
if !grep"network error" /var/log/messages
^1i+MHMg?0thenecho"There is no network error mentioned in the syslog"
a.OIER{GQg0fi
bT NL,M9q/} a@S0
木铎校园 BBS 社区k.{[$|+x&hh7c%c

The ! is just like acommandwitharguments, that's why it is important to have a space behind it:

,r(N*Q4y?tX%EdGv[0
$ !true木铎校园 BBS 社区Ovu;l~-R7V6V!G
bash: !true: event not found
g/hOTo&]tx0

[edit]Loops

木铎校园 BBS 社区C)H0{ z e

You canloopon a condition:木铎校园 BBS 社区MC G[,KnGa

while [ 5 = 5 ]; do echo "This never stops"; done木铎校园 BBS 社区8MyUg,_$U,p]
until [ 5 = 6 ]; do echo "This never stops"; done木铎校园 BBS 社区-BiXE/W%Rb
Dk;]7k	u
木铎校园 BBS 社区.R ycb L~,F+FQ

木铎校园 BBS 社区3]LR(QS9{1x

+@5J)Hz0Vko.T0

[edit]Get your IP address

木铎校园 BBS 社区cO5K? gH J lP

Abashexample to get your IP address usinghttp://www.whatismyip.com:木铎校园 BBS 社区ve'y:z8o3V8_?*^

,l$LsF8H? f P0
lynx -dumphttp://www.whatismyip.com| grep -i "Your IP is" | awk '{ print $4; }'木铎校园 BBS 社区P*DNk oi
木铎校园 BBS 社区*hvd8Fa s

Or use this:
Q8ktb A0# ifconfig ppp0 | awk '/inet addr/{print $2}' | cut -d: -f2

%V%[ nM&V)lc0木铎校园 BBS 社区.] ~ ZOy;J

Or this:木铎校园 BBS 社区,^'K(XOb6KB2[
# ifconfig ppp0 | sed -rn 's/^.*inet addr:([^ ]+).*$/\1/p'
R@D:~'s,l%p S0木铎校园 BBS 社区 W;poy'XDqG)N~
Note that ppp0 stands for the first point-to-point-protocol device which is usually a modem. If you are using an ethernet adapter instead, replace ppp0 with eth0. You can also leave it out all together to list all the addresses associated with your computer.木铎校园 BBS 社区m7L^,e~Vz4?#Y


[edit]Some counting examples

x=0; ((x++))
-ov M3s M.K6N:`0x=0; x=$((x+1))
S4a/FB]'@Ok(\m0x=0; let x=$x+1木铎校园 BBS 社区S!u"m o%VW O
for (( x=0; x<10; x++ )) ; do echo $x ; done
&e-Y$KIg8_|0
for x in $(seq 0 9); do echo $x; done木铎校园 BBS 社区!^!c"XN%Xsi
x=0; x=$(expr $x + 1)
oG5L)b%]%r\t0x=0; x=$(echo $x + 1|bc)
J*Mu3\d7Gn0x=4; x=$(echo scale=5\; $x / 3.14|bc)
F:Z5n${/f.[F0

%Zl3w\\n*z0The first four demonstrate Bash' internal counting mechanisms, these will not use external programs and are thus safe (and fast). The last four use external programs.bc, as used in the last two examples, is the only one that supports numbers with decimals. For adding, subtracting and multiplying, you don't have to do anything special, but for division you need to specify the number of digits to keep (default is none) using the 'scale=n' line.木铎校园 BBS 社区#n*p |NV+x;JvO


[edit]Combining multiple conditions of if statements

*Sb#d*ERpj c$x0AND:

0|l_ DHN0
if((a==1 && b==2))
+n'kR{P3w(Si0

h"bm5\?}@0OR:

n3Uh?cX0
if(( a!=1 || b>10 ))木铎校园 BBS 社区3\yRpI
木铎校园 BBS 社区:p{#T"o$f vi


dN6j.Yj+j je,A'N0木铎校园 BBS 社区R [:zlPu


[edit]Conditional execution

木铎校园 BBS 社区,lU3r.U-x(ZnO6f

As stated above, you can do something like木铎校园 BBS 社区 s HTS R,|9d

scorpio:~ # if (( 5 == 5 && 6 == 6 )); then echo "five is five and six is six"; fi木铎校园 BBS 社区2ez{|W?_rHY
five is five and six is six
dHw)`JL2k^A4}0
木铎校园 BBS 社区y Y7d#{L8zWZ

We call 5 == 5 the left term and 6 == 6 the right term.Bashfirst evaluates the left term and if it is true, it evaluates the right term. If both are true, the result is true, otherwise, the result is false (boolean logic). It is an interesting effect that, if the left term is false, the right term is not even evaluated - the result will be false in any case. That means, if we replace the terms by commands, the right command will only be executed if the left command succeeded. One can use this effect:木铎校园 BBS 社区e.s ~O,j!W+T$F

scorpio:~ # ls > /tmp/dir && echo "the command succeeded"
C9FEY gy'U@0the command succeeded
W b;oR/G IJ/g!s0scorpio:~ # ls > /proc/cmdline && echo "the command succeeded"
P~lKEP3{R0/bin/ls: write error: Input/output error木铎校园 BBS 社区"v Sk-q-O,c
scorpio:~ #
@/c,wV!j }:g{7W5t0

*ps^"t;Us2|L,l0In the above example, bash tells you if the command succeded. The right command isconditionally executed. Considering a famous saying, you can even program a bird using this technology:木铎校园 BBS 社区!S"`Z~.ltd0nJ

eat || die
/l*zEXyu0

/G V[W1{w5r%P!A0This line says "eat or die" which is very useful if you want a program to exit in case it cannot perform a certain operation:

`*Tc h[R\0
touch /root/test || exit
C"z)iog0

[edit]Functions

木铎校园 BBS 社区u%L7cw@h

You can define functions forstructuredprogramming. It is also possible to hand overparametersto a function. Example:

U#gcv%D0
#!/bin/bash木铎校园 BBS 社区'YW$dD3sw
# This program calculates the square of a given number木铎校园 BBS 社区 N7~F1pZuFf
木铎校园 BBS 社区%i$t XC8ov"U1Z
function square \木铎校园 BBS 社区S_TM{ZR
{木铎校园 BBS 社区3{3O o El,yH
echo "The square of your number is "
#mm+dc+Wj PF0echo $((a*a))
x*o9y+V0y_| h0}
2q^ c{Qy W(?9z~0
z%d]O1@eJ/D,i0echo "Input a number"
b5\8Bm0h&g0read a木铎校园 BBS 社区Jk8jV5cod{
square $a木铎校园 BBS 社区pY!B,L]?Q

[edit]Renaming a set of files

(v;id2Ol HG4Q0The following example will rename all files ending in .jpeg to end in .jpg

-Y@|[y(O#M!|!L7B0
$ for file in *.jpeg; do mv $file ${file%.jpeg}.jpg; done木铎校园 BBS 社区7gFSp
xp(m4B
木铎校园 BBS 社区OO%k%E![i(Lv

mmvis a really nifty tool for doing this sort of thing more flexibly too. Therenamecommand also provides similar functionality, depending on your linuxdistribution.木铎校园 BBS 社区SU[[8no%hTd

木铎校园 BBS 社区y!_,l5BX"N/G+v l

If you have a load of files in all capital letters (common if you unzip oldDOSprograms for instance), you can use木铎校园 BBS 社区[H.K6\C-QzdnQ

$ for file in *; do mv $file $(echo $file | tr [[:upper:]] [[:lower:]]); done木铎校园 BBS 社区j}(izu
木铎校园 BBS 社区@ Q;Y2S/^XM8M,_t1~

to make all the files in the current directory lowercase.

9p4{#s:a)N)B iK0

[edit]Converting several wav files to mp3

木铎校园 BBS 社区{ b;n"N/` f^9|;L;?

This statement will convert all .wav files in a directory to mp3 (assuming you already have thelamepackageinstalled):木铎校园 BBS 社区 byZ0dw5{7y*|

for i in *.wav; do lame -h $i && rm $i; done
木铎校园 BBS 社区ysz,K2Sy5B

The double ampersand prevents rm from deleting files that weren't successfully converted.木铎校园 BBS 社区j)l+LI5g;GT_


[edit]Full file name

7]y8perd9m(k$I0Prints the full filename removing ./ and ../ and adding `pwd` if necessary. I keep this in a script calledfqn

)qp+`*{%l#~d,SN.R0
#!/bin/sh
Kff#B4nJ0木铎校园 BBS 社区,`d(vF P
# return the full filename, removing ./ ../ adding `pwd` if necessary
cS5x`H\0木铎校园 BBS 社区A^ _.Xx;r Q:h
FILE="$1"木铎校园 BBS 社区,t;["h6z"V!K-|t9OJ
木铎校园 BBS 社区+g/Y,x~r ?:z7Vt
# file dot relative木铎校园 BBS 社区d`e%_`n-r
# ./file dot relative
p r9` Cl"u-^0# ../file parent relative木铎校园 BBS 社区~(a#i2CC1[!A
# /file absolute木铎校园 BBS 社区PRV$O1\YY
while true; do木铎校园 BBS 社区'ZT$v8fbA(V
case "$FILE" in木铎校园 BBS 社区'U*vdi9Mmg
( /* )木铎校园 BBS 社区&t\ W8N1DB-o6_
# Remove /./ inside filename:木铎校园 BBS 社区k;[2D*iI ^
while echo "$FILE" |fgrep "/./" >/dev/null 2>&1; do木铎校园 BBS 社区8i7v?)pGM"]
FILE=`echo "$FILE" | sed "s/\\/\\.\\//\\//"`木铎校园 BBS 社区.|+tKLGy)_m
done
$LoF+_:I5s0# Remove /../ inside filename:木铎校园 BBS 社区Wi@9z[J9X3u
while echo "$FILE" |grep "/[^/][^/]*/\\.\\./" >/dev/null 2>&1; do木铎校园 BBS 社区In8{bOE)d7|1M9bU
FILE=`echo "$FILE" | sed "s/\\/[^/][^/]*\\/\\.\\.\\//\\//"`
(|g0{5a ML \0done木铎校园 BBS 社区"?'L2IC`b }-B
echo "$FILE"
rFGL9R'N0exit 0
U U ej^.u%H uKt0;;木铎校园 BBS 社区?/M)N:LE,}O8C)klYN|
木铎校园 BBS 社区 _@S8j9J0|
(*)木铎校园 BBS 社区 }*Z!]i-b'k$\S2[k
FILE=`pwd`/"$FILE"木铎校园 BBS 社区8r:_'[#? b*y
;;木铎校园 BBS 社区-`6k'\)tA(U p y
esac木铎校园 BBS 社区(},dck&]y bS7T

)po Rx qa e4W}0done
6_/F![&w Z,T0

[edit]Resolving a link

2a6DD&R`*aS0This little script follows symbolic links wherever they may lead and prints the ultimate filename (if it exists!) (note - it uses the previous script accessed asfqn木铎校园 BBS 社区 m:?w,U9z {;o"bm

#!/bin/sh
4uq7i,W8{6za0
e2W-XW#H2p]9M&j1sA0# prints the real file pointed to by a link木铎校园 BBS 社区/|2gVAC
# usage: $0 link木铎校园 BBS 社区.a7~:Z#bdq Oj!Ix

sI'I J6^3O_0ORIG_LINK="$1"
7J$a!mES0LINK=`fqn "$1"`
`C(ddLh(Hb0while [ -h "$LINK" ]; do
;OG.m f u+gY4VQ.g0DIR=`dirname "$LINK"`
9[X,N0QT'OJ@0木铎校园 BBS 社区)c&X8Mm2?
# next link is everything from "-> "
]-q_1c9[0LINK=`ls -l "$LINK" |sed "s/^.*-> //"`木铎校园 BBS 社区l@n i1W)I!|#C3t

te$~h JZg2] IN0LINK=`cd "$DIR"; fqn "$LINK"`
WO1MIt C_5En-{0if [ ! -e "$LINK" ]; then木铎校园 BBS 社区*CW(S*jBF D0f
echo "\"$ORIG_LINK\" is a broken link: \"$LINK\" does not exist" >&2
-_txK1lKz\0exit 1
1n&|4jJI*B0fi
2`1D/q#[Ya2ktW0done
pZ2]`$S(X,[D0echo "$LINK"
Y/F;AD9i0exit 0
?/w FGW4U0
#!/bin/bash
xb0cM{Y8`0# this is a lot simpler, and just as useful (but doesn't do dead link checking)
5ikC\:D O0ORIG_LINK="$1"
:\#zt/]&hV9F0TMP="$(readlink "$ORIG_LINK")"
gK0IN3p:HQ0while test -n "$TMP"; do
6`A LA w'?0ORIG_LINK="$TMP"木铎校园 BBS 社区}#\T Wi fQi
TMP="$(readlink "$ORIG_LINK")"木铎校园 BBS 社区M4e5QRL D Lq
done木铎校园 BBS 社区LSX)j2MZ S,c7Uc
echo "$ORIG_LINK"
.a*r}(J{h&i0

[edit]Viewing a file according to its type

;D:@/cG'HR)mg X-i0I save this as a script calledvand it is my universal viewing script - it can be extended to any kind of file and to use your favourite tools for each type of file. It uses thefileutility to determine what sort of file it is and then invokes the correct tool. It automatically adapts to being used on the system console or under X.木铎校园 BBS 社区!s1dxr9r EapP

木铎校园 BBS 社区l&W;SZ%Vc!@/N@9g

(note - this uses a prior scriptfqn)木铎校园 BBS 社区B"K/A4wV dO4q x

#! /bin/sh木铎校园 BBS 社区5U,HHP.t
# View files based on the type of the first one:
z.Ca n%`*L0# Relies partly on 'less' to invoke an appropriate viewer.
,v{xB^8k0# Make sure than you have this set:
d+O9p ||m#hY/`0# LESSOPEN="|lesspipe.sh %s"
u@kHKc4Wi0
*p%H?Yg0FIRST="$1"木铎校园 BBS 社区+k ~+F,K7h@7X C:k
FULL=`fqn $FIRST`木铎校园 BBS 社区-H2H6B!n:WA$p(R3c.m
木铎校园 BBS 社区-[` GF y%i)_7_o*b
# if we are being piped to, just run less
`Z1@*cJ/pe3Y t0[ -z "$FIRST" -o ! -r "$FIRST" ] && exec less "$@"
:_(xqm9[E S+S+{&uw0
oF+q xJ0O8{9\ t-vf0# some file types beyond what /usr/bin/lesspipe.sh handles:木铎校园 BBS 社区2we9V@WS6UPD C5?P
case "$FIRST" in
7I4Q ?)N#i,E)V0*.cpio.bz2) bunzip2 -c $1 | cpio -ctv 2>/dev/null |less; exit ;;木铎校园 BBS 社区7c8K+hk!S!K;}X
*.cpio) cpio -ctv $1 2>/dev/null |less; exit;;
-rmfV3~ m0esac木铎校园 BBS 社区(`*X#M VV7l lD J
木铎校园 BBS 社区+q1av1kk

m$F)~EH4]+I0TYPE=`file -L -i "$FIRST" 2>/dev/null | \
dEL)X8p#g A$h0awk '{len=length("'"$FIRST"'")+ 2; $0=substr($0, len); print $1;}'`
0e2ywBCQ0echo "Type=\"$TYPE\""木铎校园 BBS 社区s w%jV2q
case "$TYPE" in木铎校园 BBS 社区/x[%I0E ^{8g6g
image/jpeg | image/tiff | image/gif | image/x-xpm | image/*)木铎校园 BBS 社区-{iK|}y%a
xzgv "$@" ;;木铎校园 BBS 社区*O3Kli^/I%n h0~0a
application/pdf)
fW7Y k&z t.VG0XPDFGEOM=`xdpyinfo |awk '/dimensions/ {print $2}'| \
I)dS8xX1JLU-~,uF)q0awk -Fx '{printf("%dx%d+0+0", 0.60*$1, $2-35)}'`
I9A;z+U6C0xpdf -geometry $XPDFGEOM -z width "$@"木铎校园 BBS 社区Q,fI"~!VB])I)o
;;木铎校园 BBS 社区s)L-n4N1J n+A
application/postscript)
2G7X'Yr B6I0gv "$@" ;;
j0y\A_5W0application/msword)木铎校园 BBS 社区$j%t-?Hh@8W6r
if [ -z "$DISPLAY" ] ; then antiword "$@" | \
,tC#Xd#iP$x Yk0less; else soffice "$@" & fi ;;
{@;]3?`.p0text/html)木铎校园 BBS 社区!z O OHV(L X:R
if [ -z "$DISPLAY" ] ; then lynx "$@"; else dillo "$FULL" & fi ;;
2W J6j'Fko.G_0audio/mpeg)
nP;tCR:i!a[.~{rq0mpg123 "$FIRST" ;;
vs-f?1TMay.`0*)
#q;T+o4V8H[)R0less "$@" ;;
zN Y:j)Nb{ S0esac木铎校园 BBS 社区h*B2v5Cl9Ad5Z

[edit]Finding the 50 largest directories

du -S / | sort -nr | head -n50木铎校园 BBS 社区#^(P_h[2s

[edit]Auto-generating a shebang line

(echo -n '#!'; which perl; tail -n+2 foo) > bar

7d_G/whDA/bN0This will print "#!" and the path toperl, then everything except the first line (the original shebang) of the filefoo; and redirect all that to go into a filebar.

ByBGNI0

Mz7E]4@0T*T!th7p0This is really meant for use in install scripts; obviously you know where perl is on your system, but not necessarily on anybody else's system (though/usr/bin/perlis a safe guess). But you know bash is always at/bin/sh. So, instead of just saying in the documentation "change the first line .....", you can write a little shell script that puts the correct shebang line in the file and copies it to/usr/local/bin. Then, put this script in a .tar.gz file with your perl script and any documentation.

$P[$X B/O#r1[%S0

[edit]Creating an audio CD from .mp3 files

(R*wj,{0s1vU0This little script requires the mpg123 andcdrdaopackages. It uses mpg123 to create a .wav file from each mp3 in the current directory, and builds up a "TOC" file (Table Of Contents) as it goes along, using the && notation to be sure only to include successfully-converted files. Finally, it starts writing the CD.

)KF AF#hwCfM0木铎校园 BBS 社区J9E.Q8D'\

The TOC file is given a name based on the PID, and is placed in the current directory. Neither it nor the .wav files will be deleted at the end of the script, so you can always burn another copy of the CD if you want.木铎校园 BBS 社区WH A k?M] }@

#!/bin/sh木铎校园 BBS 社区Yf*Z#EV&g
tocfile="cd_$$.toc"木铎校园 BBS 社区7p'`/~nUi@p2?
echo "CD_DA" > $tocfile木铎校园 BBS 社区vV8Vm-] eqJ
for i in *mp3木铎校园 BBS 社区1t@7ek*Y,wU
do wav="`basename $i .mp3`.wav"
R,y+NT&]0mpg123 -w$wav $i\木铎校园 BBS 社区JU1f6C7]2C
&& echo -en >>$tocfile "TRACK AUDIO\nFILE \"$wav\" 0\n"木铎校园 BBS 社区 h.H{4zsg _;N6L
done木铎校园 BBS 社区2{'}Hj0W.fs
echo -e "TOC file still available at $tocfile"
XwQ5y!|th1g4Y0cdrdao write $tocfile
oV Fg1`];P%u8I0
木铎校园 BBS 社区{g5Md!s

Note: in theforstatement, you might think at first sight that it should befor i in *.mp3; but Linux doesn't care about filename extensions at all. * will match a . character; therefore, *mp3 will match everything ending in mp3 or .mp3. Those characters are unlikely to be found on the end of anything but an mp3 file.木铎校园 BBS 社区0A.o Jv&qE


[edit]Portable Indirection

$Q8^PFea4a V0Sometimes you need to use the value of a variable whose name is held in another variable. This is indirection. For example:

P(sb#W'X psF0
for V in PATH LD_LIBRARY_PATH; do echo ${!V}; done
'dei/p wp$h"_0
木铎校园 BBS 社区 Y KR E'f$Q

but that isn't portable to older shells, eg. the old Bourne shell. A portable way is to use the following instead of${!V}:

^ v4w!GpFC _0
`eval echo \\$"$V"`
/^1SK p g0

.vTY,gOdK?!H0It's not pretty but at least it works on nearly all Unixes.木铎校园 BBS 社区9BK1e]*jdV

木铎校园 BBS 社区kTW"O:Bx9H4C9W

[ someone said - "It does require that the variable be exported." Actually no. It works without exporting V on bash and on Solaris sh ]木铎校园 BBS 社区'b$\J/gxHi }


[edit]Matching Curly Brackets

cGv"E!V N0If you indent your C, Perl or PHP code in what is commonly called "K&R style", which is to say something like this

%pf[LL bv~s0Y0
# nested loop example木铎校园 BBS 社区m	lg`7L+EGp^%J
for ($i = 0; $i <= 6; ++$i) {木铎校园 BBS 社区7iwKV8^9d|9ay
for ($j = 0; $j <= $i; ++$j) {木铎校园 BBS 社区?G2yG"QedM1au
print "$i : $j ";木铎校园 BBS 社区;V3tt(wUh8[
};
Jd/X PTc^:^0print "\n";
r+t8cC$b Y'H3o/{0};
木铎校园 BBS 社区U+@6NqZ'fBU

i.e. where the opening curly bracket appears on the same line as the flow-control keyword (if, while &c.) and everything up to, but not including, the closing curly bracket is indented, then you may find this useful. I came up with it out of necessity, and thought it was just too important not to share. All it does is display the lines with a { but no following } (in Perl, these denote associative array indexes) or a } with no preceding {. In other words, just the opening and closing lines of loops, not the content. This can help you to spot those annoying missing-bracket errors.木铎校园 BBS 社区 l+yE&e3EZ

awk'/({[^}]*$)|(^[^{]*})/{print}'foo
木铎校园 BBS 社区kXu-M7R'T

Replacefoowith the filename to be examined. Or, of course, you can omit the filename and use the command in apipeline.

{.~7K c{*r0

*B*G+pe@_{'nwA"a@T0The above example would appear as

6v9fI)z XtzCs-H0i0
for ($i = 0; $i <= 6; ++$i) {木铎校园 BBS 社区;tO+^'aHyq'E$vs^~
for ($j = 0; $j <= $i; ++$j) {木铎校园 BBS 社区s{C_k
};木铎校园 BBS 社区?zd*N QA%E
};

[edit]rpminfo

木铎校园 BBS 社区e{W3iu8iE d([ S [

This is a small script that prints useful info about anrpmpackage. It was inspired by the ability oflessto give almost useful info about an rpm file throughlesspipe.sh.木铎校园 BBS 社区 ["B2qp q5|p Y

#!/bin/sh
.^ d{o7S5mU*a0echo INFORMATION: ; rpm -qi $* ; echo
-_;T F$My nG(|8~{KD0echo REQUIRES: ; rpm -qR $* ; echo木铎校园 BBS 社区 ZHZ.R%P P0X
echo PROVIDES: ; rpm -q --provides $* ; echo
]vzN4Y\ fJ,Z@7k0echo FILELIST: ; rpm -qlv $*
!g4D*WQYY2?/Q\]0

3}FP,z$K0Save it to a file calledrpminfoin yourpathandchmodit so it's executable. It is often useful topipethe output toless, as in the examples below.木铎校园 BBS 社区 J d(zrP'Gc!Q R

木铎校园 BBS 社区"gDiJ&f0r D9Q/h6L

To get info on an installed package, you can just give the package name like:

lV(Y$qqS^3aTC0
rpminfo XFree86 |less木铎校园 BBS 社区h1P	W"b ^0@*}_+ID/Nt.e,y
木铎校园 BBS 社区R&s UnMR

For a package file that you have just downloaded, give the-pcommand option, just likerpm:

1^@J$r}D7gu0
rpminfo -p XFree86-4.1.0-25.i386.rpm |less
H'C7LKqjQ0

[edit]Copy files/dirs and leave the symbol links as they are


TAG: bash Bash tips

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

关于作者