shell脚本须知

什么是shell脚本,首先它是一个脚本,并不能作为正式的编程语言,说白了就是shell脚本就是一些命令的集合。

凡是自定义的脚本建议放到/usr/local/sbin/目录下,这样的好处是方便管理和维护,且利于以后交接给接替你的管理员。

shell脚本的结构

#cat first.sh

#! /bin/bash

## This is my first shell script.

date

echo "Hello world!"

脚本要以#! /bin/bash开头,代表的意思:该文件是使用的是bash语法,如果不使用该行也是可以的,但是如果把这个脚本放到一个默认shell并非bash的系统里,那么这个脚本很有可能是不能成功执行的。

还可以适当在脚本中使用#写一些脚本相关的注释内容,如作者、创建日期或者版本等。这些并不是shell脚本一定要的,只是为了统一管理,规范化。

shell脚本的几种执行方式

  1. fork:直接使用绝对路径来执行脚本,这种方式会启动一个子shell来执行脚本。
  2. source filename:在当前shell环境下,读取并执行filename中的命令。注:该命令可用命令“.”来替代,如:source .bash_rc 与 .  .bash_rc 是等效的。
  3. exec 绝对路径:exec使用shell脚本的绝对路径在当前shell(shell会被重置到初始环境)下执行脚本,脚本执行完后会退出该shell。
  4. ./script启动一个子shell来执行脚本。
  5. sh|bash filename启动一个子shell读取并执行filename中的命令。
  • 子shell的变量结果不会被带回父shell,所以要想通过脚本设置当前shell的环境变量时,要用source命令。

shell脚本执行方式


是否需要执行权限


原因


exec


需要执行权限


由脚本主动调用shell来执行命令


fork或./


source或.


无需执行权限


由shell主动读取脚本并执行


bash或sh

使用sh命令执行一个脚本时,可以使用-x参数查看这个脚本的执行过程,在进行脚本调试时,有利于发现问题。

# sh -x first.sh

+ date

Fri Jan  822:28:23 CST 2016

+ echo ‘Hello world!‘

Hello world!

shell自定义变量

在shell脚本中定义变量,可以方便我们很方便的编辑、修改脚本,且使脚本变得简洁。

格式:变量名=值

shell数学运算

在shell中进行数学运算时,需要使用$[]括起来。

乘法运算:

# a=8;b=3;echo "$a*$b=$[$a*$b]"

8*3=24

除法运算

# a=8;b=3;echo "$a/$b=$[$a/$b]"

8/3=2

  • 默认shell是不支持小数的。如果需要小数,则需要调用bc(linux 系统中的计算器)“yum –y install bc”
  • bc不会进行四舍五入。

如果想要保留2位小树,可以这样实现。

# echo "scale=2;8/3"|bc

2.66

shell用户交互

shell脚本可以实现让用户输入一些字符串(read命令)或者让用户去选择(select语句)的行为。

read命令

# cat read.sh

#! /bin/bash

## Using ‘read‘ in shell script.

read -p "Please input a number: " x

read -p "Please input another number: " y

sum=$[$x+$y]

echo "The sum of the two numbers is: $sum"

read命令类似与visualbasic的input函数,作用是产生一个“输入行”,将用户输入的字符串赋值给read命令语句后的变量。

# sh read.sh

Please input a number: 2

Please input another number: 10

The sum of the two numbers is: 12

select语句

select 循环提供了一个简单的方法来创建一个编号的菜单,用户可从中选择。它是有用的,当你需要从列表中选择,要求用户选择一个或多个项目。

select 表达式是一种bash的扩展应用,动作包括:

l  自动用1,2,3,4列出菜单(没有echo指令,自动显示菜单)

l  自动read输入选择(没有 read指令,自动输入)

l  赋值给变量(没有赋值指令,自动输入数字后,赋值字符串给变量)

语法格式:

selectvariable in value1 value2 value3 …

do

command

done

例子:

# cat sel.sh

#! /bin/bash

echo "What is your favourite OS?"

select var in "Linux" "Gnu Hurd" "FreeBSD" "Other"

do

break

done

echo "You have selected $var"

# sh sel.sh

What is your favourite OS?

1) Linux

2) Gnu Hurd

3) Free BSD

4) Other

#? 2

You have selected Gnu Hurd

  • select本身就是一个循环,break就是当选择后,就跳出循环。
  • 当变量内容含有空格时,应该将其用""括起来。

select一般和case语句结合使用,以上面一个例子为例,将它优化下:

# cat sel.sh

#! /bin/bash

echo "What is your favourite OS?"

select var in "Linux" "Gnu Hurd" "FreeBSD" "Other"

do

case $var in

Linux)

break;;

"Gnu Hurd")

break;;

"Free BSD")

break;;

Other)

break;;

*)

echo "Please enter anumber:(1-4)";;

esac

done

echo "You have selected $var"

  • select虽然循环却在第一次选择之后不再显示菜单,只循环输入。

# sh sel.sh

What is your favourite OS?

1) Linux

2) Gnu Hurd

3) Free BSD

4) Other

#? 6

Please enter a number:(1-4)

#? 8

Please enter a number:(1-4)

#? 3

You have selected Free BSD

Shell脚本预设变量

# cat option.sh

#! /bin/bash

sum=$[$1+$2]

echo "$0$1"+"$2"="$sum"

# sh option.sh 2 3

option.sh 2+3=5

$0是脚本本身的名字,$1是执行脚本时跟的第一个参数,$2是执行时跟的第二个参数,$3是…当然一个shell脚本的预设变量是没有限制的。

if语句

if语句是逻辑判断语句。

if几种语法格式:

1)  if 判断语句;then command;fi

2)  if 判断语句;then command;else command;fi

3)  if 判断语句

then

command

fi

4)  if 判断语句

then

command

elif 判断语句

then

command

else

command

fi

例子

# cat if1.sh

#! /bin/bash

read -p "Please input your score: " a

if ((a<60)); then

echo "You didn‘tpass the exam."

Fi

if判断语句的相关内容

在进行数值关系运算时,除了可以使用(())的形式外,还可以使用[],但不能使用>,<,=,!=这些符号,要使用-lt(小于),-gt(大于),-le(大于等于),-ge(大于等于),-eq(等于),-ne(不等于)。

  • 再使用[]时要注意空格。

例子

# cat if1.sh

#! /bin/bash

read -p "Please input your score: " a

if [ $a –lt60 ]; then

echo "You didn‘t pass theexam."

Fi

在判断语句中可以使用&&(并且)、||(或者)、!(非)

# a=10; if [ $a -lt 1 ] || [ $a -gt 5 ]; then echo OK; fi

OK

# a=5; if [ $a -gt 1 ] && [ $a -lt 10 ]; then echo OK; fi

OK

和文件相关的判断参数

  • -e :判断文件或目录是否存在
  • -d :判断是不是目录,并是否存在
  • -f :判断是否是普通文件,并是否存在
  • -r :判断文档是否有读权限
  • -w :判断是否有写权限
  • -x :判断是否可执行

例子:

# if [ -x/bin/bash ]; then echo ok; fi

ok

# if [ ! –x/bin/bash ];then chmod +x /bin/bash;fi

和变量相关的判断参数

  • -n:判断变量是否不为空
  • -z:判断变量是否为空
  • ==或=:判断变量的值是否为指定值
  • !=:判断变量的值是否非指定值

例子:

# a=;if [ -n "$a" ]; then echo "a is not null";else echo "a is null"; fi

# a=;if [ -z $a ]; then echo "a is null"; fi

a is null

判断条件也可以是一条命令

例子:

#  if grep -q ‘^mysql:‘ /etc/passwd;then echo"user mysql exitst.";fi

user mysqlexitst.

  • grep –q的作用是,过滤但不输出。

case选择语句

语法格式:

case 变量 in

value1 |value2)

command

;;

value3)

command

;;

value4)

command

;;

*)

command

;;

esac

  • 上面的结构中,不限制 value 的个数,可以使用|匹配多个值,*则代表除了上面的 value 外的其他值。

例子:

# cat case.sh

#! /bin/bash

read -p "Input a number: " n

a=$[$n%2]

case $a in

1)

echo "The number isodd."

;;

0)

echo "The number iseven."

;;

*)

echo "It‘s not anumber!"

;;

esac

这是一个判断奇偶数的脚本,%在shell中是作为取余的符号

for循环语句

for 变量名 in 循环的条件; do

command

done

这里的“循环的条件”可以写成一组字符串或者数字(用 1 个或者多个空格隔开), 也可以是一条命令的执行结果,注意要使用反单引号``.

# for i in 1 2 3 a b; do echo $i; done

1

2

3

A

B

# for i in `seq 1 5`; do echo $i;done

1

2

3

4

5

  • seq命令:用于产生从某个数到另外一个数之间的所有整数

# seq 1 5

1

2

3

4

5

while循环语句

while循环语句常常用来编写死循环的脚本,用于监控某项服务。

语句格式:

while 循环条件;do

command

done

例子:

# cat while.sh

#! /bin/bash

a=5

while [ $a -ge 1 ]; do

echo $a

a=$[$a-1]

done

把循环条件用一个:(冒号)替代,这样可以做到死循环

# cat load.sh

#!/bin/bash

shu=1

while : ; do

load=`uptime|awk ‘{print$(NF-2)}‘|cut -d. -f1`

if [ $load -gt 10 ]&& [ $shu -le 4 ] ;then

echo "system load is high."|mail -s"system load" [email protected]

shu=$[$shu+1]

sleep 30

elif [ $shu -gt 4 ];then

shu=1

sleep 3600

else

shu=1

sleep 30

fi

done

这是一个监控系统负载的脚本。没30秒检测一次系统负载,如果负载值高于10时,向[email protected]发一封告警邮件,如果连续4次负载高于10时,则休眠1小时再继续执行脚本,以避免频繁发送邮件,对管理员造成骚扰(告警收敛)。

break、continue、exit

break:退出本层循环

continue:跳过接下来的语句,直接进入下一次循环

exit:退出当前shell

#!/bin/bash
for i in `seq 1 5`;do

echo $i

if [ $i== 3 ];then break ;fi
echo $i

done

echo aaaaaaa

# sh break.sh

1

1

2

2

3

aaaaaaa

#!/bin/bash
for i in `seq 1 5`;do

echo $i

if [ $i== 3 ];then continue ;fi
echo $i

done

echo aaaaaaa

# sh continue.sh

1

1

2

2

3

4

4

5

5

aaaaaaa

#!/bin/bash
for i in `seq 1 5`;do

echo $i

if [ $i== 3 ];then exit ;fi
echo $i

done

echo aaaaaaa

# sh exit.sh

1

1

2

2

3

shell函数

函数就是把一段代码整理到一个小单元中,并给这个小单元起一个名,当用到这段代码时,直接调用这个小单元的名字即可。

函数格式:

function_name() {

command

}

函数应定义在shell脚本的开头

# cat sum.sh

#! /bin/bash

sum() {

echo$1"+"$2"="$[$1+$2]

}

sum 3 4

# sh sum.sh

3+4=7

获取网卡名对应的IP:

# cat ip.sh

#!/bin/bash

ip() {

ifconfig |grep -A1"$1 " |tail -1 |awk ‘{print $2}‘|awk -F‘:‘ ‘{print $2}‘

}

read -p "Please input the eth name: " e

myip=`ip $e`

echo "$e address is $myip"

# sh ip.sh

Please input the eth name: lo

lo address is 127.0.0.1

shell数组

定义元素:

name[下标]=value

ü  下标从0开始

定义数组:

name=(value1value2 value3 …)

删除数组:

unset name

删除元素:

unset name[下标]

打印数组的所有元素:

echo${name[*]}或echo ${name[@]}

  • 与打印变量不同,打印数值时需要使用${}将数组扩起来

打印数组:

echo${name[下标]}

打印第2个元素: echo ${a[1]}

打印数组的元素个数:

Echo${#name[@]} 或者 echo ${#a[*]}

数组分片:

echo${name[*]:下标x:下标y}

  • 限制数组的打印范围,打印下标x到下标y之间的元素

数组替换:

echo ${name[@]/value1/value2}

  • 更改数组的输出,将value1替换为value2
  • name=(${name[@]}/value1/value2)也可以通过这种形式进行赋值
时间: 2024-10-29 19:08:17

shell脚本须知的相关文章

20.5 Shell脚本中的逻辑判断;20.6 文件目录属性判断;20.7 if特殊用法;20.8 20.9 cace判断(上下)

扩展: select用法 http://www.apelearn.com/bbs/thread-7950-1-1.html 20.5 Shell脚本中的逻辑判断 格式1:if 条件 ; then 语句; fi 1. 创建if1.sh测试脚本: [[email protected] ~]# vi if1.sh a=5,如果a大于3,满足这个条件,显示ok 添加内容: #!/bin/bash a=5 if [ $a -gt 3 ] then echo ok fi 2. 执行if1.sh脚本: [[e

20.1 Shell脚本介绍;20.2 Shell脚本结构和执行;20.3 date命令用法;20.4 Shell脚本中的变量

20.1 Shell脚本介绍 1. shell是一种脚本语言 aming_linux blog.lishiming.net 2. 可以使用逻辑判断.循环等语法 3. 可以自定义函数 4. shell是系统命令的集合 5. shell脚本可以实现自动化运维,能大大增加我们的运维效率 20.2 Shell脚本结构和执行 1. 开头(首行)需要加: #!/bin/bash 2. 以#开头的行作为解释说明: 3. 脚本的名字以.sh结尾,用于区分这是一个shell脚本 4. 执行.sh脚本方法有两种:

shell脚本交互:expect学习笔记及实例详解

最近项目需求,需要写一些shell脚本交互,管道不够用时,expect可以很好的实现脚本之间交互,搜索资料,发现网上好多文章都是转载的,觉得这篇文章还不错,所以简单修改之后拿过来和大家分享一下~ 1. expect是spawn: 后面加上需要执行的shell命令,比如说spawn sudo touch testfile 1.3 expect: 只有spawn执行的命令结果才会被expect捕捉到,因为spawn会启动一个进程,只有这个进程的相关信息才会被捕捉到,主要包括:标准输入的提示信息,Li

利用SHELL脚本来验证Oracle数据库RMAN备份集的有效性

利用SHELL脚本来验证Oracle数据库RMAN备份集的有效性 作者:赵全文  网名:guestart 我们生产环境的Oracle数据库都做了RMAN备份,是采用了一周的RMAN备份保留策略:除了使用RMAN备份以外,我们还使用了爱数(Eisoo)备份软件来进行备份,可以说是做到了有备无患.可是,如果有一天,Oracle数据库由于主机层面硬件原因或是数据库层面的原因不能对外提供高可用服务的时候,假设数据丢了一大部分,我们只有用RMAN备份来进行恢复,再如果发现,RMAN备份失效了,那就往地缝里

如何在linux Shell脚本里面把一个数组传递到awk内部进行处理

前段时间和几位同事讨论过一个问题:Shell脚本里面怎样把一个数组传递到awk内部进行处理? 当时没有找到方法.前两天在QQ群里讨论awk的时候,无意间又聊起这个话题.机缘巧合之下找到一个思路,特此分享. 测试环境: [root]# head -1 /etc/redhat-release Red Hat Enterprise Linux Server release 6.5 (Santiago) [root]# awk --version | head -1 GNU Awk 3.1.7 众所周知

利用shell脚本批量修改表

最近公司里因为开发新功能,程序员需要快速在某一个库里的所有表添加字段,于是就用shell脚本简单快速实现批量修改表添加字段 #!/bin/bash export mysql_bin=/usr/local/mysql/bin export database=database export tables=`$mysql_bin/mysql -Bse "use ${database};show tables;"` for i in ${tables}         do          

Shell 脚本模拟 milter 实现黑白名单及关键词过滤

程序执行流程:1. 开始接受邮件.2. 检查发件人是否在黑名单内,如果是拒绝接受;否则继续3. 检查发件人是否在白名单内,如果是接收邮件;否则继续4. 对邮件进行关键字过滤,如果邮件中包含被过滤的关键词信息,则拒绝接收   该邮件;否则,接收该邮件. Usage: sh mailfilter.sh  [-r reject-addr] [-a add-addr][-k keywords]########################################################

Linux Shell脚本攻略(1.12)

1.12 函数和参数 和其他脚本语言一样,Bash同样支持函数,并且可以传递参数. 1.12.1 函数定义和传参 #!/bin/bash function fname() #也可以用fname()代替 { echo $1,$2; #访问参数1和参数2 echo "[email protected]"; #以列表的方式一次性打印所有参数 echo "$*"; #类似于[email protected],但是参数被作为单个实体 return 0; #返回值 } fnam

shell脚本编程学习笔记(1)

在linux上编程,离不开shell,计划好好看看shell编程,并在这里做些笔记以供有相同兴趣的人分享,主要参考<shell脚本学习指南>. 学习shell脚本编程之前,需要了解脚本编程语言和编译型语言的概念. 一般很多中型.大型的程序是用编译型语言写成的,比如C.C++.Java等.这类程序从源代码编译成目标代码,直接通过计算机执行.编译型语言执行效率比较高,大多运作于底层,处理的是字节.整数.浮点数等机器层级的对象,因此实现一个具体的功能,比如"将一个目录里的所有文件复制到另外