shell脚本编程初步–吐血整理

shell脚本编程

编程基础

程序:

程序的构成:指令 + 数据

程序的编程风格:

    过程式:以指令为中心,数据服务于指令

    对象式:以数据为中心,指令服务于数据

shell程序:提供了编程能力,解释执行

shell,perl,python语言均为高级编程语言

编程的逻辑处理方式:

    顺序执行

循环执行

选择执行

shell编程:过程式、解释执行

 

脚本基本格式

shell脚本是包含一些命令或声明,并符合一定格式的文本文件

格式要求:首行shabanng机制

#!/bin/bash

#!/usr/bin/python

#!/usr/bin/perl

 

shell脚本用途:

自动化常用命令

执行系统管理和故障排除

创建简单的应用程序

处理文本或文件

 

如何创建shell脚本

第一步:使用文本编辑器来创建文本文件

        第一行必须为shell声明序列,即shebang

            例如:#!/bin/bash

        添加注释:

            注释以#开头(以#开头的行不会被执行)

第二步:运行脚本

        给予执行权限,在命令执行上指定脚本的绝对或相对路径

        运行解释器,将脚本作为解释器程序的参数运行

   

#!/bin/bash

#author: wang

#Version: 1.0

#Description:This script displays some information about your# environment echo "Greetings. The date and time are $(date)" echo "Your working directory is: $(pwd)"

 

脚本调试:

bash –n /path/to/some_script:检测脚本中的语法错误

bash –x /path/to/some_script:调试执行

 

变量

变量即是命名的内存空间

bash变量为弱类型变量

      即无需指定类型,默认均为字符型;参与运算会自动进行隐式类型转换,变量无需实现定义,可直接调用

变量命名法则:

1、不能使用程序中保留字,如if,for…

2、只能使用数字、字母及下划线,且不能以数字开头

3、见名知义

4、统一命名法则:驼峰命名法

 

根据变量的生效范围等标准可做以下归类:

   本地变量:生效范围为当前shell进程

   环境变量:生效范围为当前shell进程及其子进程

   局部变量:生效范围为当前shell进程中某代码片段(通常为函数)

   位置变量:$1、$2…,用于表示脚本代码中调用命令行的参数

   特殊变量:$?à 前一条命令的执行结果,0表示成功,1-255表示失败

             $0à 命令本身

             $#à 参数的数量

 

本地变量:

变量赋值:name=‘value’,

可以使用引用value:

(1) 可以是直接字串; name=“root"

(2) 变量引用:name="$USER"

(3) 命令引用:name=`COMMAND`, name=$(COMMAND)

变量引用:${name}, $name

"":弱引用,其中的变量引用会被替换为变量值

'':强引用,其中的变量引用不会被替换为变量值,而保持原字符串

显示已定义的所有变量:set

删除变量:unset name

 

环境变量:

变量声明、赋值:

export name=VALUE

declare -x name=VALUE

变量引用: $name, ${name}

显示所有环境变量:

export

env

printenv

删除: unset name

bash有许多内建的环境变量: PATH, SHELL, USRE,UID,HISTSIZE, HOME, PWD, OLDPWD, HISTFILE, PS1

 

只读和位置变量:

 

只读和位置变量

只读变量:只能声时,但不能修改和删除

readonly name

declare -r name

一般是常量中会使用

declare –rx name 表示既是一个常量又是一个环境变量

但是随shell进程终止而终止

位置变量:在脚本代码中调用通过命令行传递给脚本的参数

$1, $2, …:对应第1、第2等参数,shift [n]换位置

$0: 命令本身

$*: 传递给脚本的所有参数,全部参数合为一个字符串

$@: 传递给脚本的所有参数,每个参数为独立字符串

$#: 传递给脚本的参数的个数

$@ $* 只在被双引号包起来的时候才会有差异

 

运算

算术运算:

+, -, *, /, %取模(取余), **(乘方)

实现算术运算:

(1) let var=算术表达式

(2) var=$[算术表达式]

(3) var=$((算术表达式))

(4) var=$(expr arg1 arg2 arg3 …)

(5) declare –i var= 数值

(6) echo ‘算术表达式’ | bc

乘法符号有些场景中需要转义,如*

bash有内建的随机数生成器:$RANDOM(1-32767)

echo $[$RANDOM%50] :0-49之间随机数

如果要表示2-51:echo $[$RANDOM%50+2]

表示1-n: echo $[$RANDOM%N+1]

赋值

增强型赋值:

+=, -=, *=, /=, %=

let varOPERvalue

例如:let count+=3

自加3后自赋值

自增,自减:

let var+=1

let var++

let var-=1

let var–

 

逻辑运算

true, false

1     0

与:

1 与 1 = 1

1 与 0 = 0

0 与 1 = 0

0 与 0 = 0

或:

1 或 1 = 1

1 或 0 = 1

0 或 1 = 1

0 或 0 = 0

非:!

! 1 = 0

! 0 = 1

短路运算:

短路与:

第一个为0,结果必定为0;

第一个为1,第二个必须要参与运算;

短路或:

第一个为1,结果必定为1;

第一个为0,第二个必须要参与运算;

异或:^

异或的两个值,相同为假,不同为真

 

例如:

#command1 && command2

command1为“假”,则command2 不会再执行

否则,command1为“真”,则command2必须执行

#command1 || command2

command1为“假”,则command2 必须执行

否则,command1为“真”,则command2不会再执行

要实现user1用户不存在就添加用户user1

id user1 || useradd user1

 

 

退出状态

进程使用退出状态来报告成功或失败

0 代表成功,1-255代表失败

$? 变量保存最近的命令退出状态

例如:

ping-c1-W1hostdown&>/dev/null

echo$?

退出状态码

bash自定义退出状态码

exit [n]:自定义退出状态码;

注意:脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命令后面的数字

注意:如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码

 

 

 

条件测试

判断某需求是否满足,需要由测试机制来实现;

专用的测试表达式需要由测试命令辅助完成测试过程;

评估布尔声明,以便用在条件性执行中

若真,则返回0

若假,则返回1

测试命令:

test EXPRESSION

[ EXPRESSION ]

[[ EXPRESSION ]]

注意:EXPRESSION前后必须有空白字符

 

条件性的执行操作符

根据退出状态而定,命令可以有条件地运行

&& 代表条件性的AND THEN

 

|| 代表条件性的OR ELSE

例如:

grep-qno_such_user/etc/passwd ||echo'Nosuchuser'

Nosuchuser

ping-c1-W2station1&>/dev/null >&& echo"station1isup" || (echo'station1isunreachable';exit1)

station1isup

test命令

长格式的例子:

test "$A"=="$B" && echo "Stringsareequal"

test "$A" -eq "$B" && echo "Integersareequal"

简写格式的例子:

[ "$A" == "$B" ] && echo "Stringsareequal"

[ "$A" -eq "$B" ] && echo "Integersareequal"

数值测试:

-gt:是否大于;

-ge:是否大于等于;

-eq:是否等于;

-ne:是否不等于;

-lt:是否小于;

-le:是否小于等于;

字符串测试:

==:是否等于;

>:ascii码是否大于ascii码

<:是否小于

!=:是否不等于

=~:左侧字符串是否能够被右侧的PATTERN所匹配

 

注意:此表达式一般用于[[ ]]中;

-z "STRING":字符串是否为空,空为真,不空为假

-n "STRING":字符串是否不空,不空为真,空为假

注意:用于字符串比较时的用到的操作数都应该使用引号

 

文件测试

存在性测试

-a FILE:同-es

-e FILE: 文件存在性测试,存在为真,否则为假;

存在性及类别测试

-b FILE:是否存在且为块设备文件;

-c FILE:是否存在且为字符设备文件;

-d FILE:是否存在且为目录文件;

-f FILE:是否存在且为普通文件;(存在为真)

-h FILE 或-L FILE:存在且为符号链接文件;

-p FILE:是否存在且为命名管道文件;

-S FILE:是否存在且为套接字文件;

文件权限测试:

-r FILE:是否存在且可读

-w FILE: 是否存在且可写

-x FILE: 是否存在且可执行

 

文件特殊权限测试:

-g FILE:是否存在且拥有sgid权限;

-u FILE:是否存在且拥有suid权限;

-k FILE:是否存在且拥有sticky权限;

文件大小测试:

-s FILE:是否存在且非空;

非空为真,空为假

文件是否打开:

-t fd:fd表示文件描述符是否已经打开且与某终端相关

-N FILE:文件自上一次被读取之后是否被修改过(读先发生,写后发生)

就是读的时间比较旧

 

双目测试:

FILE1 –ef  FILE2: FILE1与FILE2是否指向同一个设备上的相同inode(硬链接)

FILE1 –nt  FILE2: FILE1是否新于FILE2;(修改的时间)

FILE1 –ot  FILE2: FILE1是否旧于FILE2;(修改的时间)

组合测试条件

第一种方式:

COMMAND1 && COMMAND2 并且

COMMAND1 || COMMAND2 或者

! COMMAND

如:[ -e FILE ] && [ -r FILE ]

第二种方式:

EXPRESSION1 -a EXPRESSION2 并且

EXPRESSION1 -o EXPRESSION2 或者

! EXPRESSION

必须使用测试命令进行,即进行test或者[ ];

 

意思是只要主机名没有定义或者主机名为默认就改为www.magedu.com

# [ -z “$HOSTNAME” -o $HOSTNAME "== "localhost.localdomain" ] && hostname www.magedu.com

 

判断/bin/cat是否为可执行文件,如果是就调用

# [ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab

 

使用read命令来接受输入

使用read来把输入值分配给一个或多个shell变量:

-p:指定要显示的提示

-t:TIMEOUT

read从标准输入中读取值,给每个单词分配一个变量

所有剩余单词都被分配给最后一个变量

read -p “Enter a filename:“ FILE

条件选择if语句

选择执行

注意:if语句可嵌套

单分支

if 判断条件:then

条件为真的分支代码

fi

双分支

if 判断条件; then

条件为真的分支代码

else

条件为假的分支代码

fi

多分支

if CONDITION1; then

if-true

elifCONDITION2; then

if-ture

elifCONDITION3; then

if-ture

else

all-false

fi

逐条件进行判断,第一次遇为“真”条件时,执行其分支,而后结束整个if语句

 

条件判断:case语句

case 变量引用in

PAT1)

分支1

;;

PAT2)

分支2

;;

*)

默认分支

;;

esac

   

case支持glob风格的通配符:

*:任意长度任意字符

?:任意单个字符

[]:指定范围内的任意单个字符

a|b:a或b


练习:

1、写一个脚本/root/bin/createuser.sh,实现如下功能:使用一个用户名做为参数,如果指定参数的用户存在,就显示其存在,否则添加之;显示添加的用户的id号等信息

代码:

[root@localhost bin]# cat creatuser.sh

#!/bin/bash

 

echo "Please input a username:"

read username

id $username &> /dev/null

if [[ $? -eq 0 ]];then

    echo "用户已存在"

else

    useradd $username;echo "用户$username添加成功"

    id $username

fi

测试:

[root@localhost bin]# creatuser.sh

Please input a username:

wang

用户已存在

[root@localhost bin]# creatuser.sh

Please input a username:

li

用户li添加成功

uid=1007(li) gid=1007(li) groups=1007(li)

 

2、写一个脚本/root/bin/yesorno.sh,提示用户输入yes或no,并判断用户输入的是yes还是no,或是其它信息

代码:

[root@localhost bin]# cat yesorno.sh

#!/bin/bash

read -p "Please input yes or no:" x

case $x in

[Yy][Ee][Ss]|[Yy])

    echo you have inputde yes

;;

[Nn][Oo]|[Nn])

    echo you have inputed no

;;

*)

    echo illegal input

;;

esac

测试:

[root@localhost bin]# yesorno.sh

Please input yes or no:yes

you have inputde yes

 

[root@localhost bin]# yesorno.sh

Please input yes or no:Yes

you have inputde yes

 

[root@localhost bin]# yesorno.sh

Please input yes or no:no

you have inputed no

 

[root@localhost bin]# yesorno.sh

Please input yes or no:No

you have inputed no

 

[root@localhost bin]# yesorno.sh

Please input yes or no:aa

illegal input

 

3、写一个脚本/root/bin/filetype.sh,判断用户输入文件路径,显示其文件类型(普通,目录,链接,其它文件类型)

代码:

[root@localhost bin]# cat filetype.sh

#!/bin/bash

 

echo "请输入一个文件路径"

read file

if [[ -L $file ]];then

    echo $file 是一个符号链接文件

elif [[ -f $file ]];then

    echo $file 是一个普通文件

elif [[ -b $file ]];then

    echo $file 是一个块设备文件

elif [[ -c $file ]];then

    echo $file 是一个字符设备文件

elif [[ -d $file ]];then

    echo $file 是一个目录文件

elif [[ -p $file ]];then

    echo $file 是一个管道文件

elif [[ -S $file ]];then

    echo $file 是一个套接字文件

else

    echo No such file

fi

测试:

[root@localhost bin]# filetype.sh

请输入一个文件路径

/etc/rc1.d

/etc/rc1.d 是一个符号链接文件

[root@localhost bin]# filetype.sh

请输入一个文件路径

/etc/issue

/etc/issue 是一个普通文件

[root@localhost bin]# filetype.sh

请输入一个文件路径

/testdir

/testdir 是一个目录文件

[root@localhost bin]# filetype.sh

请输入一个文件路径

/run/systemd/notify

/run/systemd/notify 是一个套接字文件

[root@localhost bin]# filetype.sh

请输入一个文件路径

/dev/sda

/dev/sda 是一个块设备文件

[root@localhost bin]# filetype.sh

请输入一个文件路径

/dev/null

/dev/null 是一个字符设备文件

[root@localhost bin]# filetype.sh

请输入一个文件路径

/dev/zero

/dev/zero 是一个字符设备文件

 

4、写一个脚本/root/bin/checkint.sh,判断用户输入的参数是否为正整数

[root@localhost bin]# cat checkini.sh

代码:

#!/bin/bash

 

echo "Please input a number"

read num

if [[ -z $num ]];then

    echo "至少要输入一个数值"

exit

fi

 

NUM=$(echo $num |egrep -o '^\-?[[:digit:]]+$')

if [[ $num == $NUM ]];then

 

   if [[ $num -gt 0 ]];then

    echo $num 是一个正整数

   elif [[ $num -eq 0 ]];then

    echo 输入的是0

   else

    echo $num 是一个负整数

   fi

 

else

    echo $num 不是一个整数

fi

测试:

[root@localhost bin]# checkini.sh

Please input a number

0

输入的是0

[root@localhost bin]# checkini.sh

Please input a number

1

1 是一个正整数

[root@localhost bin]# checkini.sh

Please input a number

-8

-8 是一个负整数

[root@localhost bin]# checkini.sh

Please input a number

sss

sss 不是一个整数

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

(0)
Mr.LeeMr.Lee
上一篇 2016-08-18
下一篇 2016-08-18

相关推荐

  • 初识linux:计算机的组成及功能

    一、描述计算机的组成及功能。 由冯诺伊曼提出计算机体系结构(5大部件)控制器(Controller):是整个计算机的中枢神经,其功能是对程序规定的控制信息进行解释,根据其要求进行控制,调度程序、数据、地址,协调计算机各部分工作及内存与外设的访问等。运算器(Datapath):运算器的功能是对数据进行各种算术运算和逻辑运算,即对数据进行加工处理。 (cpu由控…

    2017-12-03
  • Linux基础知识(二)

     本文的主要内容是:  1.Linux上的基本文件管理命令  2bash的特性及其命令状态返回值  3.bash的花括号展开机制  4.文件的元数据信息有哪些,分别表示什么含义,如何查看?如何修改文件的时间戳信息  5如何定义一个命令的别名,如何在命令中引用另一个命令的执行结果?  &nb…

    Linux干货 2016-09-25
  • 浅谈netbios及其相关内容

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://jeffyyko.blog.51cto.com/28563/141086        Netbios想必大家都有接触。对于netbios的理解,我以前…

    Linux干货 2015-03-26
  • 硬链接和软链接的区别

    硬链接和软链接在文件系统实现上的区别决定了两者之间功能上的不同,也就是说硬链接和软链在文件系统上两者实现的方式不同,让其各自具有不同的功能和特色,也决定了各自的优点和缺点。接下同文件系统上创建硬链接和软链接看各自的特点。 一文件系统上创建硬链接 下面命令是在文件系统上创建一个硬链接: ~]# ln test /testdir/t…

    Linux干货 2016-10-29
  • raid介绍

    raid介绍 在生产环境中,服务器所需的存储容量比较大,一般都会选择磁盘阵列来走存储。 阵列的优点 多个磁盘合成一个“阵列”来提供更好的性能、冗余,或者两者都提供 首先在I/O能力上,多个磁盘并行读写,可以提高读写的速度。 阵列所提供的磁盘冗余,提升存储设配的耐用性。 RAID实现的 外接式磁盘阵列:通过扩展卡提供适配能力 内接式RAID:主板集成RAID控…

    2017-06-24
  • Linux中的文件查找和解压缩

         Linux的文件查找 概述:      本章将主要介绍在Linux中怎样查找文件和解压缩。需要我们掌握的知识有:locate和find 命令的使用,以及如何使用压缩和解压缩工具。 一、Linux文件查找      在文件系统上常常需要根据文件的各种属…

    Linux干货 2016-09-01

评论列表(1条)

  • 马哥教育
    马哥教育 2016-08-19 15:17

    博客作业要按时完成,压得太多,你就越不想写了。