Linux脚本编写基础 1
一、构建基本脚本 1
1 开头 1
2 变量 2
3 重定向 2
4 查看退出状态码 $? 3
二、 使用结构化命令 4
1 if then 4
2 if then else 4
3 嵌套if 5
4 test 命令 5
5 复合条件测试 7
6 if then的高级特性 7
1) 双尖括号 7
2) 双方括号 8
3)case命令 8
Linux脚本编写基础
http://os.51cto.com/art/201003/186779.htm
《Linux命令行与shell脚本编程大全 第2版》
如果将多个命令一起运行,可用分号隔开,例如 date;who 为了方便起见,可以将输入的多个繁琐的命令写入一个shell脚本文件中,然后运行这个文件即可。
一、构建基本脚本
1 开头
!#/bin/sh
必须在文件的第一行,符号!#后面指定要使用的shell。
其余行用#来表示注释,直到一行的结束。
当编译好脚本后,需要在命令行运行 chmod +x filename 或chmod u+x filename,
./filename来运行。
为了让命令中产生一些输出,可以用echo ,用单引号或者双引号将文本括起来。
Echo “this’s is a test”
Echo ‘we say “it is so easy” ,so good’
若想在同一行显示一个文本字符串作为该命令输出提示,用-n ,echo -n “the time and date are”
2 变量
对变量赋值
a=”hell”
打印变量a的内容
echo “a is “
Echo
aNum=2Echo“thisisthe
a
N
u
m
=
2
E
c
h
o
“
t
h
i
s
i
s
t
h
e
{num}nd” —–>输出 this is the 2nd
Echo “the cost of the item is $15”—–>输出 the cost of the item is $15
环境变量和用户变量
环境变量
echo UID:
UID—输出UID:100echoHOME:
U
I
D
—
输
出
U
I
D
:
100
e
c
h
o
H
O
M
E
:
HOME —输出 HOME:/root
用户变量
可以是任何不超过20个字母,且变量名区分大小写,在变量,等号和值之间不能出现空格。
Value1=10
Value2=
value1Echotheresultvalueis
v
a
l
u
e
1
E
c
h
o
t
h
e
r
e
s
u
l
t
v
a
l
u
e
i
s
value2 输出 the result is 100
若value2=value1
Echo the result value is $value2 输出 the result is value1
反引号`
date +%y%m%d` #告诉date命令将日期显示为两数字的年月日组合。
today=
Echo the testing is
today输出thetestingisFriOct911:13:01CST2015Ls/usr/bin−al>log.
t
o
d
a
y
输
出
t
h
e
t
e
s
t
i
n
g
i
s
F
r
i
O
c
t
9
11
:
13
:
01
C
S
T
2015
L
s
/
u
s
r
/
b
i
n
−
a
l
>
l
o
g
.
today
3 重定向
命令 > 文件 覆盖之前文件的内容
命令 >> 文件 追加到文件
Wc
if [ “he” = “he” ]
if [
va
v
a
ba ] 大于号需要加\进行转义一下
then
echo
vaisgreaterthan
v
a
i
s
g
r
e
a
t
e
r
t
h
a
n
ba
else
echo
vaislessthan
v
a
i
s
l
e
s
s
t
h
a
n
ba
Fi 输出baseball is less than hockey
-n -z用来检查一个变量是否含有数据;-n用来判断长度是否非0.-z用来判断长度是否为0
var=””
if [ -n “
var”]thenecho
v
a
r
”
]
t
h
e
n
e
c
h
o
var is not empty
else
echo $var is empty
Fi 输出 is empty
5 复合条件测试
6 if then的高级特性
1)双尖括号
Var=10
if ((
var∗∗2>90))then((var1=
v
a
r
∗
∗
2
>
90
)
)
t
h
e
n
(
(
v
a
r
1
=
var**2))
echo the square of
varis
v
a
r
i
s
var1
Fi 输出 the square of 10 is 100
2)双方括号
if [[
USER==r∗]]thenechotheuseris
U
S
E
R
==
r
∗
]
]
t
h
e
n
e
c
h
o
t
h
e
u
s
e
r
i
s
USER 输出 the user is root
fi
3)case命令
case
USERinrich|root)echo“welcome
U
S
E
R
i
n
r
i
c
h
|
r
o
o
t
)
e
c
h
o
“
w
e
l
c
o
m
e
USER,please enjoy your visit”::
testing )
./1.sh: line 107: syntax error near unexpected token newline'
rich | root] 对于这个命令的用法还没有弄清楚
./1.sh: line 107:
echo “special testing account”::
*)
echo “sorry,you are bot allowed here”::
Esac 输出 welcome
USER,pleaseenjoyyourvisit三、更多的结构化命令1forForvarinlistDo命令Done或者Forvarinlist;Do命令Done例如:fortestinidon\’tknowif“this′ll”work;doechothenextstateis
U
S
E
R
,
p
l
e
a
s
e
e
n
j
o
y
y
o
u
r
v
i
s
i
t
三
、
更
多
的
结
构
化
命
令
1
f
o
r
F
o
r
v
a
r
i
n
l
i
s
t
D
o
命
令
D
o
n
e
或
者
F
o
r
v
a
r
i
n
l
i
s
t
;
D
o
命
令
D
o
n
e
例
如
:
f
o
r
t
e
s
t
i
n
i
d
o
n
\’
t
k
n
o
w
i
f
“
t
h
i
s
′
l
l
”
w
o
r
k
;
d
o
e
c
h
o
t
h
e
n
e
x
t
s
t
a
t
e
i
s
test
Done
输出
the next state is i
the next state is don’t
the next state is know
the next state is if
the next state is this’ll
the next state is work
下面的这个不知道为何不行
file=qwe qwe是一个文件名
for state in cat $file
do
echo “visit beautiful $state”
Done 输出cat: qwe: No such file or directory
以下是qwe文件中的内容。
cat qwe
dfd
dfdf
dfdf
dfdf
df
df
df
1)IFS内部字段分隔符
默认情况下,bash shell 会将空格、制表符、换行符当作字段分隔符。
可修改IFS的值使其只能识别换行符:IFS=$’\n’
以下这个输出也有问题 ,不知道为什么
if [ -d “
file”]thenecho“
f
i
l
e
”
]
t
h
e
n
e
c
h
o
“
file is a directory”
elif [ -f “
file”]then“
f
i
l
e
”
]
t
h
e
n
“
file is a file”
fi
done
输出
/root/01/11 is a directory
./1.sh: line 138: /root/01/1.c is a file: No such file or directory
./1.sh: line 138: /root/01/1.sh is a file: No such file or directory
./1.sh: line 138: /root/01/1.txt is a file: No such file or directory
./1.sh: line 138: /root/01/2.txt is a file: No such file or directory
./1.sh: line 138: /root/01/a.out is a file: No such file or directory
./1.sh: line 138: /root/01/count.c is a file: No such file or directory
./1.sh: line 138: /root/01/hockey is a file: No such file or directory
./1.sh: line 138: /root/01/log. is a file: No such file or directory
./1.sh: line 138: /root/01/log.151009 is a file: No such file or directory
./1.sh: line 138: /root/01/log.151012 is a file: No such file or directory
./1.sh: line 138: /root/01/qwe is a file: No such file or directory
./1.sh: line 138: /root/01/rpm.list is a file: No such file or directory
./1.sh: line 138: /root/01/test is a file: No such file or directory
2 C风格的for命令
for (( i=1; i<=10; ++i ))
do
echo “the next number is $i”
Done
输出
the next number is 1
the next number is 2
the next number is 3
the next number is 4
the next number is 5
the next number is 6
the next number is 7
the next number is 8
the next number is 9
the next number is 10
3 while命令
While test command
Do
other command
Done
4 until命令
Until test commands
Do
Other commands
Done
三、处理用户输入
$# 这个变量可以统计命令行中输入了多少个参数。
初识sed和gawk
1)Sed
sed options script file
sed编辑器自身不会修改文本文件的数据,只会将修改后的数据发送到STDOUT.
Sed -e s/test/big test/
用big test替换test
Sed -f rule.txt 2.t 用-f选项指定文件,过滤规则在文件中
Cat rule.txt
S/you/I/
S/are/am/
2)Gawk
Gawk options program file
Gawk ‘{print “hello John!”}’
Print命令:将文本打印到STDOUT。
Gawk中默认的字段分隔符是空白字符(礼服)。
从文本中读取gawk的规则
Cat gawk.rule
{
Test=”’s home directory is ”
print
1test
1
t
e
s
t
6 }
Gawk -F: -f gawk.rule /etc/passwd
可以用BEGIN命令和END命令,打印处理数据前和后的Log
gawk ‘BEGIN { print “the data4 file contents:” } { print $0 } END { print “End of life” }’ data4
the data4 file contents:
line1
line2
line3
line4
End of life
[root@localhost 01]#
3)sed编辑器基础
Sed ‘s/字符串/替换成的字符串/替换标记’
有4钟可用的替换标记:
数字:表明新文本将替换第几处匹配的地方
G:替换所有的
P:打印出原来行的内容
sed ‘/very/s/good/bad/g w 22’ 2.txt
thest y you are good or bad, not good
very bad,so bad 表示只修改了very开头的行中的字符。
[root@localhost 01]#
sed ‘s/good/bad/g p w 22’ 2.txt
thest y you are bad or bad, not bad
thest y you are bad or bad, not bad
very bad,so bad
very bad,so bad 即显示 又全部替换 又将替换的保存了起来
Sed编辑器会采用正则表达式的特性来帮助很好的匹配模式。
[root@localhost 01]# sed ‘2{
s/so/very/
s/good/buautiful/
}’ 2.txt
thest y you are good or bad, not good
very buautiful,very good
[root@localhost 01]#
删除命令sed ‘2d’ 2.txt 删除第2 行
Sed ‘d’ 2.txt 删除所有
Sed ‘2,3d’ 2.txt 删除第2行和3行
Sed ’3,$d’ 2.txt从第三行删除到结尾
修改命令 sed ‘3c\how are you ‘
正则表达式
正则表达式区分大小写,识别空格,还包括以下特殊字符:
.*[]……^{}+?|()
如果要使用某个特殊字符作为文本字符,必须转义,前面加上 \
^ 脱字符:在行首检查,
[root@localhost 01]# echo “this ^ is a test” | sed -n ‘/s ^/p’
this ^ is a test
[root@localhost 01]# 若将该字符放到模式中的其他位置而不是开头,则当作普通字符。
$ 行尾查找
过滤出数据流中的空白行
[root@localhost 01]# cat 2.txt
thest y you are good or bad, not good
very good,so good
very good,so good
[root@localhost 01]# sed ‘/^/d’ 2.txt
thest y you are good or bad, not good
very good,so good
very good,so good
[root@localhost 01]# 将^
/d’ 2.txt thest y you are good or bad, not good very good,so good very good,so good [root@localhost 01]# 将^
组合在一起,不加任何文本,过滤出数据流中的空白行。
. 点字符:用来匹配任意的单字符,若点字符旁边没有字符,则不成立。
[] 字符数组:
[root@localhost 01]# cat 2.txt
thest y you are good or bad, not good
very good,so good
very good,so good
this test is at line two.
that is so good
at school
[root@localhost 01]# sed -n ‘/[^ch]at/p’ 2.txt
this test is at line two.
通过排除字符组,正则表达式模式会匹配c或h之外的任何字符,但即使是排除,字符数组仍然必须匹配一个字符,因此at开头的仍然未能匹配模式。
使用区间,单破折号。
[root@localhost 01]# echo “146g” |sed -n ‘/^[0-9][0-9][0-9][a-z]$/p’
146g
[root@localhost 01]#
- 星号:说明该字符将在匹配模式中出现0次或者多次。
[root@localhost 01]# echo “color” | sed -n ‘/colou*r/p’
color
[root@localhost 01]#
扩展正则表达式
问号 :类似于*号,不过前面的字符表示可以出现0次或者1次,不会匹配多次出现的该字符。
[root@localhost 01]# echo “beeet” | gawk ‘/be?t/{print 0}’
[root@localhost 01]# echo “bet” | gawk ‘/be?t/{print
0}’ [root@localhost 01]# echo “bet” | gawk ‘/be?t/{print
0}’
bet
[root@localhost 01]#
如果字符数组中的字符出现了0次或者1次,模式匹配就成立。但如果两个字符都出现了,或者如果一个字符出现了两次,模式匹配都不成立。
[root@localhost 01]# echo “beeet” | gawk ‘/be?t/{print 0}’
[root@localhost 01]# echo “bet” | gawk ‘/be?t/{print
0}’ [root@localhost 01]# echo “bet” | gawk ‘/be?t/{print
0}’
bet
[root@localhost 01]# echo “beat” | gawk ‘/b[ae]?t/{print 0}’
[root@localhost 01]# echo “bat” | gawk ‘/b[ae]?t/{print
0}’ [root@localhost 01]# echo “bat” | gawk ‘/b[ae]?t/{print
0}’
bat
[root@localhost 01]# echo “bet” | gawk ‘/b[ae]?t/{print 0}’
bet
[root@localhost 01]# echo “bt” | gawk ‘/b[ae]?t/{print
0}’ bet [root@localhost 01]# echo “bt” | gawk ‘/b[ae]?t/{print
0}’
bt
[root@localhost 01]#
Sed进阶
Sed编辑器包含了3个用来处理多航文本的特殊命令。
N:将数据流中的下一行加进来创建一个多行组来处理。
D: 删除多行组中的一行
P:打印多行组中的一行
在脚本中使用sed
PMS :包管理系统 linux中广泛使用的是dpkg和rpm