`
qindongliang1922
  • 浏览: 2148824 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
7265517b-f87e-3137-b62c-5c6e30e26109
证道Lucene4
浏览量:116361
097be4a0-491e-39c0-89ff-3456fadf8262
证道Hadoop
浏览量:124625
41c37529-f6d8-32e4-8563-3b42b2712a50
证道shell编程
浏览量:58522
43832365-bc15-3f5d-b3cd-c9161722a70c
ELK修真
浏览量:70404
社区版块
存档分类
最新评论

跟散仙学shell编程(一)

阅读更多
前面散仙已经把Linux基础的shell命令系列的博客完工,如果没有任何linux基础的朋友,建议先从shell命令开始学习,如果有一定基础的就可以直接跳过。从本篇起,散仙要写的是关于shell编程系列的知识。


前面我们例子里面的命令,基本都是单个执行的,但是在linux下,只有把命令组合成一个脚本,发挥的作用,才是巨大的,这就类似于一个砖头没啥用处,但是用很多砖头,我们就可以盖一座大厦,这样它们的价值就体现出来了。


在linux中我们可以使用分号分开执行2个命令:

[root@h1 ~]# who ;date
root     pts/0        2014-08-08 02:55 (192.168.46.22)
2014年 08月 08日 星期五 03:39:43 CST
[root@h1 ~]# 

我们也可以放脚本里执行,编写一个shell脚本的头部生命通常是#!/bin/bash开头,除了这个开头的其他的#开头都是注释内容:
vi test.sh编辑一个脚本
#!/bin/bash

#我是注释的内容
date
who

[root@h1 ~]# sh test.sh 
2014年 08月 08日 星期五 03:46:15 CST
root     pts/0        2014-08-08 02:55 (192.168.46.22)
[root@h1 ~]# 


两种调用方法,没有权限,可以赋值权限:
[root@h1 ~]# sh test.sh 
2014年 08月 08日 星期五 03:46:15 CST
root     pts/0        2014-08-08 02:55 (192.168.46.22)
[root@h1 ~]# ./test.s
-bash: ./test.s: 没有那个文件或目录
[root@h1 ~]# ./test.sh
-bash: ./test.sh: 权限不够
[root@h1 ~]# chmod u+x test.sh 
[root@h1 ~]# ll
总用量 328476
-rw-r--r--  1 root   root 143775368 7月  28 19:30 abc1.txt
-rw-------. 1 root   root      1087 6月  13 19:06 anaconda-ks.cfg
-rw-r--r--  1 root   root        52 7月  31 21:29 count2.txt
-rw-r--r--  1 root   root        52 7月  31 19:46 count.txt
-rw-r--r--. 1 root   root  96183833 6月   9 17:27 hadoop-2.2.0.tar.gz
-rw-r--r--  1 root   root         1 7月  31 21:25 hh.txt
drwxr-xr-x  3 root   root      4096 7月  29 04:47 hivesrc
-rw-r--r--. 1 root   root      2111 6月  16 13:10 initserver.sh
-rw-r--r--. 1 root   root      7995 6月  13 19:06 install.log
-rw-r--r--. 1 root   root      3384 6月  13 19:06 install.log.syslog
drwxr-xr-x  2 root   root      4096 7月  31 21:19 intest
lrwxrwxrwx  1 root   root        12 7月  31 21:45 jdk -> jdk1.7.0_25/
drwxr-xr-x. 8 search  143      4096 6月   6 2013 jdk1.7.0_25
-rwx------. 1 root   root  96316511 11月 20 2013 jdk-7u25-linux-x64.gz
drwxr-xr-x  3 root   root      4096 7月  31 21:33 li
drwxr-xr-x  3 root   root      4096 7月   9 04:08 lo
drwxr-xr-x  3 root   root      4096 7月   9 04:08 login
-rw-r--r--  1 root   root      1048 6月  19 03:31 setlimit.sh
drwxr-xr-x  2 root   root      4096 8月   5 01:44 test
drwxr-sr-x  2 root   abc       4096 8月   6 01:53 testidr
-rwxr--r--  1 root   root        46 8月   8 03:43 test.sh
drwxr-xr-x  3 root   root      4096 6月  20 02:51 tsethadoop
[root@h1 ~]# ./test.sh 
2014年 08月 08日 星期五 03:47:10 CST
root     pts/0  


如何输出一行文本,类似于JAVA里面的System.out.println()功能,linux里面的echo提供了这个功能,

如果字符串里面出现双引号,就使用单引号括起来,如果出现了单引号,就用双引号括起来,如果即出现了单引号,也出现了双引号,那么就要用\转义:
[root@h1 ~]# echo "a's dog"
a's dog
[root@h1 ~]# echo "a's"" dog"
a's dog
[root@h1 ~]# echo "a's"abc" dog"
a'sabc dog
[root@h1 ~]# echo "a's\"abc\" dog"
a's"abc" dog
[root@h1 ~]# echo 'a 'dog' "abc"'
a dog "abc"



echo -n 参数可以避免末尾换行,类似System.out.print()
echo -n  "conent:"
date

[root@h1 ~]# sh a.sh 
conent:2014年 08月 08日 星期五 04:00:14 CST


echo支持在字符串中,使用linux环境变量,可以正确输出:
[root@h1 ~]# echo "my home is $HOME"
my home is /root
[root@h1 ~]# 


用户变量定义通过等号赋值,注意等号左右不能有空格,变量名区分大小写
[root@h1 ~]# more a.sh 

name="我是三劫散仙"

echo "info: $name"

[root@h1 ~]# sh a.sh 
info: 我是三劫散仙
[root@h1 ~]# 

变量之间的赋值:
[root@h1 ~]# more a.sh 

name="我是三劫散仙"

name2=$name


echo "info: $name2"

[root@h1 ~]# sh a.sh 
info: 我是三劫散仙
[root@h1 ~]# 

把一个shell命令赋值给一个变量,使用反引号:
[root@h1 ~]# more b.sh 


test=`date;who`

echo -n "输出的内容是什么呢,大家来看下:"

echo $test
[root@h1 ~]# sh b.sh 
输出的内容是什么呢,大家来看下:2014年 08月 08日 星期五 04:14:37 CST root pts/0 2014-08-08 02:55 (192.168.46.22)
[root@h1 ~]# 


反引号的功能,类似于JavaScript里面的eval关键字的功能,可以解析字符串命令
通过这样,我们就可以生成文件时,以时间命名:

[root@h1 ~]# more c.sh 


#注意date后面有空格隔开,否则会出错

filename=`date +%y%m%d`

echo "我是文件里的内容" > log.$filename
[root@h1 ~]# more log.140808 
我是文件里的内容
[root@h1 ~]# 


输出重定向命令:
>覆盖模式重定向
>>追加模式重定向

输入重定向命令
<
内联输入重定向
<<

输出重定向相信大家用的很多,输入的重定向可能用的不多,下面散仙举几个例子:
[root@h1 ~]# wc < a.sh 
 8  5 65
[root@h1 ~]# 

输出重定向,可以把一个文件的内容,发送给命令进行统计

这三个数字的含义,代表文本的行数,词数,和字节大小,说明,有8行,5个单词,65字节

内联重定向,允许交互式的读入,在你定义好的开头,与结束符之间,追加统计进行统计:

[root@h1 ~]# wc << B
> a b 1
> d c 2
> B
 2  6 12
[root@h1 ~]# 


结束符可以随便定义,散仙在这里是B


下面要说的是管道命令:|

[root@h1 ~]# rpm -qa | sort
acl-2.2.49-6.el6.x86_64
attr-2.4.44-7.el6.x86_64
audit-2.2-2.el6.x86_64
audit-libs-2.2-2.el6.x86_64
authconfig-6.1.12-13.el6.x86_64
b43-openfwwf-5.2-4.el6.noarch
basesystem-10.0-4.el6.noarch
bash-4.1.2-15.el6_4.x86_64
binutils-2.20.51.0.2-5.36.el6.x86_64
bridge-utils-1.2-10.el6.x86_64
bzip2-1.0.5-7.el6_0.x86_64
bzip2-libs-1.0.5-7.el6_0.x86_64
ca-certificates-2013.1.94-65.0.el6.noarch
centos-release-6-5.el6.centos.11.1.x86_64
checkpolicy-2.0.22-1.el6.x86_64
chkconfig-1.3.49.3-2.el6_4.1.x86_64
coreutils-8.4-31.el6.x86_64
coreutils-libs-8.4-31.el6.x86_64
cpio-2.10-11.el6_3.x86_64
 



rpm -qa可以查询已经安装的软件包,然后重定向到sort命令进行排序。
重定向命令可以使用多个:
[root@h1 ~]# ll | more | sort
drwxr-sr-x  2 root   abc       4096 8月   6 01:53 testidr
drwxr-xr-x  2 root   root      4096 7月  31 21:19 intest
drwxr-xr-x  2 root   root      4096 8月   5 01:44 test
drwxr-xr-x  3 root   root      4096 6月  20 02:51 tsethadoop
drwxr-xr-x  3 root   root      4096 7月  29 04:47 hivesrc
drwxr-xr-x  3 root   root      4096 7月  31 21:33 li
drwxr-xr-x  3 root   root      4096 7月   9 04:08 lo
drwxr-xr-x  3 root   root      4096 7月   9 04:08 login
drwxr-xr-x. 8 search  143      4096 6月   6 2013 jdk1.7.0_25
lrwxrwxrwx  1 root   root        12 7月  31 21:45 jdk -> jdk1.7.0_25/
-rw-------. 1 root   root      1087 6月  13 19:06 anaconda-ks.cfg
-rw-r--r--  1 root   root      1048 6月  19 03:31 setlimit.sh
-rw-r--r--  1 root   root       127 8月   8 04:20 c.sh
-rw-r--r--  1 root   root 143775368 7月  28 19:30 abc1.txt
-rw-r--r--  1 root   root         1 7月  31 21:25 hh.txt
-rw-r--r--. 1 root   root      2111 6月  16 13:10 initserver.sh
-rw-r--r--  1 root   root        25 8月   8 04:20 log.140808
-rw-r--r--. 1 root   root      3384 6月  13 19:06 install.log.syslog
-rw-r--r--  1 root   root        52 7月  31 19:46 count.txt
-rw-r--r--  1 root   root        52 7月  31 21:29 count2.txt
-rw-r--r--  1 root   root        65 8月   8 04:11 a.sh
-rw-r--r--. 1 root   root      7995 6月  13 19:06 install.log
-rw-r--r--  1 root   root        90 8月   8 04:14 b.sh
-rw-r--r--. 1 root   root  96183833 6月   9 17:27 hadoop-2.2.0.tar.gz
-rwx------. 1 root   root  96316511 11月 20 2013 jdk-7u25-linux-x64.gz
-rwxr--r--  1 root   root        46 8月   8 03:43 test.sh
总用量 328492
[root@h1 ~]# 


接下来,我们看下如何在shell中,执行数学运算:
[root@h1 ~]# expr 1+5
1+5
[root@h1 ~]# expr 1 + 5
6
[root@h1 ~]# expr 1 * 8
expr: 语法错误
[root@h1 ~]# expr 1 \* 8
8
[root@h1 ~]# expr 9 / 3
3
[root@h1 ~]# expr 9 / 5
1
[root@h1 ~]# 


expr 后面跟一个表达式,注意运算式左右必须有一个空格
这是比较传统的用法,linux里面可以有计算器bc模块,如果你的linux系统里面没有,就使用yum install bc命令安装一个

[root@h1 ~]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
12 * 5.8
69.6
8 * 4 / 2
16
5 / 3
1
5 / 3.0
1
4.44 / 2
2
scale=4
3 / 8
.3750
10 / 11
.9090
scale=2
5 / 2
2.50
10 / 3
3.33

默认的是不保留小数的,我们可以通过scale设置小数点位。
最后使用quit命令退出程序。

下面我们看看如何在脚本中,使用bc命令:
[root@h1 ~]# more bc.sh 



out=`echo "scale=4;  10 / 3" | bc`

echo "输出的内容如下:$out"
[root@h1 ~]# sh bc.sh 
输出的内容如下:3.3333
[root@h1 ~]# 


我们还可以结合,内联重定向使用bc计算器,在脚本里
[root@h1 ~]# more cc.sh 



var1=10.23
var2=9
var3=1

var4=`bc << EOF
scale=4
a1 = ($var1+$var2)
b1 = ($var2+$var3)
a1 + b1
EOF
`

echo "最终的结果是: $var4"
[root@h1 ~]# sh cc.sh 
最终的结果是: 29.23
[root@h1 ~]# 



下面我们看下退出脚本的状态码:
使用变量$?
[root@h1 ~]# date
2014年 08月 08日 星期五 05:16:38 CST
[root@h1 ~]# echo $?
0
[root@h1 ~]# dates
-bash: dates: command not found
[root@h1 ~]# echo $?
127
[root@h1 ~]# 


1,0代表成功
2,1代表通用的未知错误
3,126代表命令不可执行
4,127代表没找到命令
5,128无效的退出参数
6,128+xlinux信号x的严重错误
7,130代表命令通过Ctrl+C终止
8,255退出状态码越界

在JAVA编程中,我们都知道使用System.exit可以终止虚拟机运行,那么在linux中,我们也有一样的终止方法类似于JAVA中的return关键字exit;

[root@h1 ~]# more t.sh 


echo "上面的会打印"

sleep  5

exit 


echo "我会被打印出来么?"


[root@h1 ~]# sh t.sh 
上面的会打印
[root@h1 ~]# echo $?
0
[root@h1 ~]# 


当然我们也可以执行返回的状态码:
[root@h1 ~]# cat t.sh 


echo "上面的会打印"

sleep  5

exit  88


echo "我会被打印出来么?"


[root@h1 ~]# sh t.sh 
上面的会打印
[root@h1 ~]# echo $?
88
[root@h1 ~]# 



状态码最大是255,超过255的,一律会被取模值,这一点需要注意、

1
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics