学习shell scripts

1. 为什么要学习shell编程?

         许多人会问,为什么要学习shell脚本编程?我学的是linux,又不是编程,其实对于个人用户可能用处不是很大,但是当你在为公司的成千上完的服务器做维护时,可能没有shell编程的话可能把人累死也无法完成任务,一千台服务器要做相同的工作,总不能在一千台服务器上敲一遍命令,况且人在做大量的无聊的工作极易犯错。又或者你需要在晚上3点备份数据库,你不可能晚上爬起来开电脑连接到公司服务器上去操作吧,这个写个脚本加到crontab 完事,当你写了shell脚本,执行一遍就能轻松解决这样的问题。

2. shell脚本基础:

         shell脚本是包含一些命令或声明,并符合一定格式的文本文件首行shebang机制:(声明解释器,否则使用当前shell的默认解释器,为了避免发生错误强烈建议不要省略)一般使用#作为注释内容,但是除了行首除外,如下为三种声明:

#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl

shell脚本一般用文本编辑器创建,并给文件赋予执行权限(也可以用bash解释器解释执行),bash命令可以解释脚本。

范例:

#!/bin/bash
#author:jackcui
#description: first bash script  //描述信息
echo “hello world!”       //打印hello world!
 调试运行:
bash  -n /root/bin/first_script    //检查脚本中语法错误
bash  -x  / root/bin/first_script  //调试执行

3. 变量(命令的内存空间):

1)变量类型

         字符型:数字,字母,下划线等

         数值型:整型,浮点型          

2)本地变量:对当前shell生效,对其子shell等无效

         可以是直接字符串:name=”root”

变量引用:name=$USER 如果USER变量后面还有字符,要用{}括起来,$是引用变量相当于变量存放的值,给变量赋值时,前面是变量本身,后面用变量赋值时后面时用的变量的值要加$

         命令引用:name`COMMAND`

         注释:引号的使用类似于正则表达式,可以使用setunset显示定义的所有变量

3)环境变量:对当前shell及其子shell生效

         对设置了本地变量的变量使用exportdeclare进行声明

         export name=root 

         一般可以使用exportenv显示所有的环境变量,unset取消变量的声明

         declare –x name=root

4)局部变量:对某一断代码生效

5)位置变量:用$1,$2,${10}表示用于脚本运行时传递给它的参数

6)特殊变量:$?, $0, $*,$@,$#表示和参数相关的变量

4. 算术运算:

         bash支持算术运算,不支持浮点运算:+  –  *  /  %  ** (加,减,乘,除,取模,乘方)乘法符号有时需要转义

1let var=算术表达式     eglet sum=3+5

2var=$[算术表达式]        eg: $[3+5]

3var=$((算术表达式))     eg: $((3+5))

4declare –i var=5

5var=$(expr arg1 arg2 arg3)

6echo ‘算术表达式’ |bc

7)产生随机数:echo $ [$RANDOM%50]产生0-49之间的随机数因为是对50取余数,random范围(1-32767

5. 逻辑运算:(true 1false 0

         与:全11

         或:有11

         非:取反

         短路与&&:第一个操作数为0,结果为0,第一操作数为1,第二操作数要运算

         短路或:第一操作数为1结果为1,第一操作数为0,计算第二操作数

         异或^:两个操作数相同为假,不同为真

6. 聚集命令:

1 ;为分割符聚集 date; who |wc –l

2)()打开子shell,命令执行完,退出子shell (date;who |wc -l)>> /tmp/trace

3{} 在当前shell执行,但是第一个括号后要加空格,最后一个命令之间要加分号

eg

[root@centos7 ~]# {  ls -l /root/bin|head -n3; ls -ld /root/bin;}
total 72
-rwxr-xr-x. 1 root root 315 Aug 13 15:39 A2Bsum.sh
-rwxr-xr-x. 1 root root 214 Aug 13 11:02 argsnum.sh
drwxr-sr-x. 2 root root 4096 Aug 14 16:27 /root/bin

7. 增强赋值

  +=  -=  *=  /=  %=  ++  —

8. 退出状态:

  0表示成功,1-255表示失败。 eg :ll a.txt ;echo $? 可以看到上一个命令是否执行成功,可以在bash脚本自定义退出码,根据退出码,判断在哪里出错,类似于网页404

9.  字符串测试比较:

         ==  是否等于,两边都应该是字符串,不能使用正则表达式

         >  是否大于

         <  是否小于

         != 支持正则表达式

         =~ 左侧字符串能否被右边的匹配,支持正则表达式

         -z 字符串是否为空,空为真

         -n 字符串是否非空,非空为真


注释:使用 判断[[  ]] ,使用正则表达式不能使用””括正则表达式

示例:

1==示例:

[root@centos7 ~]# a=root
[root@centos7 ~]# [[ $a == root ]]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]#

2> < 比较ASCII码大小:

[root@centos7 ~]# a=roou
[root@centos7 ~]# [[ $a < root ]]
[root@centos7 ~]# echo $?
1
[root@centos7 ~]# [[ $a > root ]]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]#

3=~  -z  -n

[root@centos7 ~]# a=341234
[root@centos7 ~]# [[ $a =~ [[:digit:]]+ ]]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# [[ -z $a ]]
[root@centos7 ~]# echo $?
1
[root@centos7 ~]# [[ -n $a ]]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]#

     

10. 文件测试:

1)存在行测试:

         -a file  -e 文件是否存在

2)存在性及其类别测试,先判断是否存在,然后是是否为符合条件(8种类型的文件都能测试):

-b 是否为块设备文件

-c 是否为字符设备

-d 是否是目录文件

-f 是否为普通文件

-h -L 存在是否是符号链接

-p 是否为管道文件

-S 是否为管道文件

文件权限测试(先判断是否存在,再判断权限):

-r  是否可读

-w 是否可写

-x 是否可执行

-g 是否拥有sgid

-u 是否拥有suid权限

-k 是否拥有sticky权限

3)大小及访问测试:

-s 是否存在且非空

-N 文件从上一次读取之后是否被修改过

-O 当前有效用户是否是文件属主

-G当前有效用户是否是文件属组

11. 组合测试:&& || -a  -o

[root@centos7 bin]# [ $USER == "jack" -o $USER == "root" ]
[root@centos7 bin]# echo $?
0
[root@centos7 bin]# echo $USER
root
[root@centos7 bin]#

12. 使用read命令接受输入

[root@centos7 ~]# cat cc.sh
#!/bin/bash
read -p "read some var: " aa  bb  dd
echo "aa is: $aa    bb is: $bb dd is: $dd "
[root@centos7 ~]# bash cc.sh
read some var: aa bb cc dd ee
aa is: aa    bb is: bb dd is: cc dd ee

注释:读入变量时每一个read定义的变量都会对应一个输入,最后一个变量接受剩余的输入,-p打印提示信息 -t超时时间

13. 条件选择if语句:

1)单分支:

格式:

if 判断条件 ;  then

 条件为真的分支代码   

fi

2)双分支:

格式:

if 判断条件 ; then

         条件为真的分支代码

else

         条件为假的分支代码

fi

3)多分支:

格式:

if 判断条件1 ; then

         条件1为真分支代码

elif 判断条件2 ; then

         条件2为真的分支代码

else

         所有条件为假的分支代码

fi

示例:

[root@centos7 testdir]# cat /testdir/multiif.sh
#!/bin/bash
#author:jackcui
if [ "$USER" == "root" ];then
   echo "hello root!"
elif [ "$USER" == "jack" ];then
   echo "hello jack! how are you?"
else
   echo "YOU ARE NOT PERMISION LOGIN!"
fi
 [root@centos7 testdir]# bash multiif.sh
hello root!
[root@centos7 testdir]# chmod a+x multiif.sh
[root@centos7 testdir]# su - jack
Last login: Thu Aug 11 21:52:45 CST 2016 on pts/1
[jack@centos7 ~]$ bash /testdir/multiif.sh
hello jack! how are you?

14. 条件判断:case语句:

格式:

case 变量引用 in

pat1

         分支1

         ;;

pat2)

         分支2

         ;;

*)

         默认分支

         ;;

esac

示例:

[root@centos7 testdir]# cat caseTest.sh
#!/bin/bash
#author:jackcui
read -p "Input conditional number: " con
case $con in
[124])
    echo "this is first condition!"
    ;;
3)
  echo "this is third condition!"
   ;;
5)
 echo "this is 5th condition!"
   ;;
*)
  echo "this conditional is false!"
    ;;
esac

补充:case支持glob风格的通配符 * []  a|b

* 任意长度字符,?任意单个字符 [] 指定给范围内的任意单个字符  a|b  ab

15.各种循环for,while,until

1for

格式:

for 变量名 in 列表;do

         循环体

done

补充:in后的列表:1)直接给出列表。2{1..100},给出连续范围。3$(seq 起始 递增 结束) 4)使用通配符如*.conf 5)变量引用 $@ , $*

for循环打印9*9乘法表

[root@centos7 bin]# cat 9\*9.sh 
#!/bin/bash
i=1
j=1
for i in {1..9};do
  for j in `seq 1 $i`;do
    let mul=$i*$j
    echo -ne " $j*$i=$mul\t" 
   done
      echo -e "\n"
done

for循环打印国际棋盘(支持输入颜色代码,支持任意大小,颜色代码41-47,

重置=0,黑色=40,红色=41,绿色=42,黄色=43,蓝色=44,洋红=45,青色=46,白色=47 )

#!/bin/bash
#author:jackcui
read -p "please input width,color1 color2: " width col1 col2
for ((i=1;i<=8;i++));do
   for ((k=1;k<=width;k++));do
       for ((j=1;j<=8;j++));do
           for ((m=1;m<=width;m++));do
            let rem=(i+j)%2
               if [ $rem -eq 0 ];then
                echo -en "\e[${col1}m  \e[0m"
               else
                echo -en "\e[${col2}m  \e[0m"
               fi
           done
       done
        echo  -en "\n"
   done
done

2while先判断条件是否满足,true则执行循环,否则跳出循环

格式:

while条件;do

         循环体

done

示例:

while打印1-100的和

#!/bin/bash
#author:jackcui
i=1
   while ((i<=100));do
    (( sum+=i++ ))
  done  
 echo "the sum is : $sum"

3until  false进入循环,直到条件满足就跳出循环

格式:

until 条件;do

         循环体

done

until示例:

[root@centos7 bin]# cat until99.sh 
#!/bin/bash
i=1;j=1;sum=0
until [ $i -gt 9 ];do
    until [ $j -gt $i ];do
       ((sum=j*i))
    echo -ne "$j*$i=$sum\t"
       ((j++))
    done
   echo "" 
  ((j=1))
  ((i++))
 done

原创文章,作者:jack_cui,如若转载,请注明出处:http://www.178linux.com/37215

(0)
jack_cuijack_cui
上一篇 2016-08-18
下一篇 2016-08-18

相关推荐

  • 基于Keepalived构建高可用集群配置实例(HA Cluster)

    什么是集群 简单的讲集群(cluster)就是一组计算机,它们作为一个整体向用户提供一组网络资源。这些单个的计算机系统就是集群的节点(node)。一个理想的集群是,用户从来不会意识到集群系统底层的节点,在他/她们看来,集群是一个系统,而非多个计算机系统。并且集群系统的管理员可以随意增加和删改集群系统的节点。 关于更详细的高可用集群我们在后面再做详解…

    Linux干货 2016-11-03
  • DNS资源记录类型

      资源记录   资源记录(Resource Records),简称RRs。是指每个域所包含的与之相关的资源。例如,每个RR都包括这个域的所属(RR是从哪个域名中得到的),类型(什么样的资源存在于这个RR中),TTL(time to live,存活时间)等等。 DNS包括七大资源记录 A记录:也称为主机记录,是DNS名称到IP地址的映射,用于正向解…

    Linux干货 2017-02-08
  • zabbix之报警功能的实现

    一、注册微信公众号 首先申请微信公众平台https://mp.weixin.qq.com/一个人最多申请5个公众号,所以还是可以的 申请完之后就可以根据腾讯的提示使用微信公众号了,然后用你自己的微信扫描关注微信号。 就可以看到用户数了,接下来的就要使用的用户的微信ID号了。点击用户查看用户的微信ID号。在浏览器查看用户的微信ID号。就是那个红色的ID了。 h…

    Linux干货 2017-03-27
  • 马哥教育网络班N22期+第2周课程练习

    马哥教育网络班N22期+第2周课程练习 1 linux上的常用文件管理类命令 1.1 常用文件查看命令 MORE命令 作用:分屏显示查看文件内容 用法:more file 查看翻页方式: B键向上 一页 空格向下一页 enter键一行一行翻阅 翻到最后一行自动退出 LESS命令 作用:分屏显示查看文件内容 用法:less file 查看方式:less命令与查…

    Linux干货 2016-08-29
  • LINUX命令帮助

    命令帮助 在维护和使用Linux系统时,常常会遇到忘记命令的使用方法,遇到一个比较陌生的命令,又或者想知道这个命令是什么的情况可以查看命令使用帮助。 LINUX命令使用帮助可参考:程序自身的帮助文档、官方文档、官方站点、LINUX的发行版官方文档、其他网站或者搜索引擎 LINUX命令分为内部命令(shell内置的命令)和外部命令,内部命令和外部命令…

    Linux干货 2017-05-28
  • 对ssh的简单理解

    ssh:secure shell,protocol,22、tcp安全的远程登录 具体的软件实现:openssh:ssh协议的开源实现,centos默认安装dropbear:另一个开源实现ssh协议版本v1:基于crc-32做MAC,不安全;man-in-middle 已淘汰v2:双方主机协议选择安全的MAC方式基于DH算法做密钥交换,基于RSA或DSA实现身…

    2017-09-29