学习shell script

目录

一.什么是shell script

二.shell编写注意事项:

三.假设我的程序文件名是/home/haha/shell.sh,该如何执行这个文件?

1.直接命令执行:

2.以bash进程来执行:

四.脚本的编写

示例一:

示例二:

示例三:

示例四:

五.script的执行方式区别(source,shscript,./script)

1.利用直接执行方式来执行script

2.利用source来执行脚本:在父进程中执行

3.利用test命令的测试功能

4.利用判断符号[]

5.shell script的默认变量($0,$1...)

6.条件判断式

(1)利用if...then

(2)利用case...esac判断

7.循环(loop)

(1)for...do...done(固定循环)

(2)while do done,until do done(不定循环)

示例一:

示例二:

8.利用function功能

9.shell script的追踪与调试

示例一:测试sh02.sh有无语法问题

示例二:将sh10.sh的执行过程全部列出来


一.什么是shell script

Shell script是利用shell的功能所写的一个“程序”,这个程序是是使用纯文本文件,将一些shell的语法与命令(含外部命令)写在里面,搭配正则表达式,管道命令与数据流重定向等功能,以达到我们所想要的处理目的。

二.shell编写注意事项:

1.命令的执行是从上而下,从左而右地分析执行;

2.命令,参数间的多个空白都会被忽略掉;

3.空白行也将被忽略掉,并且[tab]按键所得的空白同样视为空格键;

4.如果读取到一个Enter符号(CR),就尝试开始执行该行(或改串)命令;

5.至于如果一行的内容太多,则可以使用“\[Enter]”来扩展至下一行;

6.“#”可作为批注。任何加在#后面的数据将全部被视为批注文字而被忽略。

三.假设我的程序文件名是/home/haha/shell.sh,该如何执行这个文件?

1.直接命令执行:

shell.sh文件必须要具备可读可执行(rx)的权限,然后:

(1)绝对路径:使用/home/haha/shell.sh来执行命令;

(2)相对路径:假设工作目录在/home/haha/,则使用./shell.sh来执行;

2.以bash进程来执行:

通过“bash shell.sh”或“sh shell.sh”来执行。

四.脚本的编写

示例一:

编写一个简单的script

[leiyuxing@centos6 ~]$ mkdir scripts

[leiyuxing@centos6 ~]$ cd scripts/

[leiyuxing@centos6 scripts]$ vim sh01.sh
#!/bin/bash
# program:
#     This program shows "Hello leiyuxing!" in your screen.
# History:
# 2016/8/19 leiyuxing     First release
PATH=/bin:/sbin:/use/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo -e "Hello leiyuxing! \a \n"
exit 0


程序编写说明:

1.第一行#!/bin/bash声明这个script使用的shell名称

因为我们使用的是bash,所以必须以“#!/bin/bash”来声明这个文件内的语法使用bash的语法。当这个程序被执行时,就能够加载bash的相关环境配置文件(一般来说就是non-login shell的~/.bashrc),并且执行bash来使我们下面的命令能执行。这个至关重要,如果没有设置好这一行,程序可能无法执行,因为系统可能无法判断该程序需要使用寿命shell来执行。

2.程序内容说明

整个script当中,除了第一行的“#!”是用来声明shell的之外,其他#都是“批注”的用途,

故上面的程序中第二行以下就是用来说明整个程序的基本数据。一般来说,建议你养成说明该script的内容与功能,版本信息,作者,联系方式,建立日期,历史记录等习惯,这有助于将来程序的改写与调试。

3.环境变量的声明

PATH与LANG(如果有使用到输出相关的信息时)是当中最重要的!如此一来程序可直接执行一些外部命令,二不必写绝对路径。

4.主要程序部分

echo这一行。

5.告知执行结果

一个命令的执行成功与否,可使用$?这个变量来查看,也可以利用exit 这个命令中断程序,并且传回一个数值给系统。这个程序中博主使用exit 0,这代表离开script并且回传一个0给系统,所以我执行完这个script程序后,若接着执行echo $?则可得到0的值。至此我知道了,利用exit n(n是数字)的功能,我们可以自定义错误信息,让程序变得更加聪明。

用上面的执行方法查看下结果:

[leiyuxing@centos6 scripts]$ sh sh01.sh

Hello leiyuxing!

也可使用

[leiyuxing@centos6 scripts]$ chmod a+x sh01.sh

[leiyuxing@centos6 scripts]$ ./sh01.sh

Hello leiyuxing!

示例二:

利用read命令的用途编写一个script,让用户输入first name 和last name,最后在屏幕上显示“Your full name is:”内容

[leiyuxing@centos6 scripts]$ vim sh02.sh
#!/bin/bash
# program:
#     User inputs his first name and last name. program shows his full name.
# History:
# 2016/8/20 leiyuxing     First release
PATH=/bin:/sbin:/use/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
 
read -p "Please input your first name: " firstname//提示用户输入
read -p "Please input your last name: " lastname//提示用户输入
echo -e "\nYour full name is : $firstname $lastname"//结果由屏幕输出
[leiyuxing@centos6 scripts]$ sh sh02.sh



Please input your first name: lixing

Please input your last name: leiyuxing

 

Your full name is : lixing leiyuxing

示例三:

随日期变化:利用日期进行文件的创建

假设我想创建三个空的文件(通过touch),文件名最开头由用户输入决定,假设用户输入filename,那今天的日期是2016/08/20,我想要以前,昨天,今天的日期来创建这些文件,即filename_20160818,filename_20160819,filename_20160820,该如何是好?

[leiyuxing@centos6 scripts]$ vim sh03.sh
#!/bin/bash
# program:
#     Program creates three files, which named by user's input
#     and date command
# History:
# 2016/8/20 leiyuxing    First release
PATH=/bin:/sbin:/use/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
#1.让用户输入文件名,并取得fileuser这个变量
echo -e "I will use 'touch' command to create 3 files."  #纯粹显示信息
read -p "Please input your filename: " filename      #提示用户输入
#2.为了避免用户随意按【Enter】,利用变量功能分析文件名是否有设置
filename=${fileuser:-"filename"}   #开始判断有否配置文件名
#3.开始利用date命令取得所需的文件名
date1=$(date --date='2 days ago' +%Y%m%d) #前两天的日期
date2=$(date --date='1 days ago' +%Y%m%d) #前一天的日期
date3=$(date +%Y%m%d) #今天的日期
file1=${filename}${date1} #下面三行在配置文件名
file2=${filename}${date2}
file3=${filename}${date3}
#4.创建文件名
touch "$file1"
touch "$file2"
touch "$file3"

验证结果:

[leiyuxing@centos6 scripts]$ sh sh03.sh

I will use 'touch' command to create 3 files.

Please input your filename: file1

[leiyuxing@centos6 scripts]$ sh sh03.sh

I will use 'touch' command to create 3 files.

Please input your filename: file2

[leiyuxing@centos6 scripts]$ sh sh03.sh

I will use 'touch' command to create 3 files.

Please input your filename: file3

[leiyuxing@centos6 scripts]$ ls

filename20160818  filename20160819  filename20160820  sh01.sh  sh02.sh  sh03.sh

示例四:

如果我们要用户输入两个变量,然而将两个变量的内容相乘,最后输出相乘结果

[leiyuxing@centos6 scripts]$ vim sh04.sh
#!/bin/bash
# program:
#     User inputs 2 integer numbers; program will cross these two numbers.
# History:
# 2016/8/20 leiyuxing     First release
PATH=/bin:/sbin:/use/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo -e "You SHOULD input 2 numbers,I will cross them! \n"
read -p "first number: " firstnu
read -p "second number: " secnu
total=$(($firstnu*$secnu))
echo -e "\nThe result of $firstnu x $secnu is ==>$total"

验证结果:

[leiyuxing@centos6 scripts]$ sh sh04.sh

You SHOULD input 2 numbers,I will cross them!

 

first number: 4

second number: 5

 

The result of 4 x 5 is ==>20

五.script的执行方式区别(source,shscript,./script)

1.利用直接执行方式来执行script

当子进程完成后,子进程内的各项变量或操作将会结束而不会传回到父进程中

例:

[leiyuxing@centos6 scripts]$ echo $firstname $lastname

//确认了这两个变量并不存在

[leiyuxing@centos6 scripts]$ sh sh02.sh

Please input your first name: leiyuxing//这个名字是博主自己输入的

Please input your last name: leiyushen

 

Your full name is : leiyuxing leiyushen //在script运行中,这两个变量生效

[leiyuxing@centos6 scripts]$ echo $firstname $lastname

//事实上,这两个变量在父进程的bash中还是不存在的!

2.利用source来执行脚本:在父进程中执行

例:

[leiyuxing@centos6 scripts]$ source sh02.sh

Please input your first name: leiyuxing

Please input your last name: leiyushen

 

Your full name is : leiyuxing leiyushen

[leiyuxing@centos6 scripts]$ echo $firstname $lastname

leiyuxing leiyushen//有数据产生,可以生效!

3.利用test命令的测试功能

比如我要检测dm是否存在时,使用:

[leiyuxing@centos6 ~]$ test -e /dm

发现结果不会显示任何信息

但我们可以通过$?或&&及||来显示整个结果:

[leiyuxing@centos6 ~]$ test -e /dm && echo "exitst" || echo "Not exist"

Not exist

最终的结果可以告知我们是“exist”还是“Not exist”

例:

首先判断一下,让用户输入一个文件名,我们判断:

(1)这个文件是否存在,若不存在给予一个“Filename does not exist”的信息,并中断程序;

(2)若这个文件存在,则判断它是文件还是目录,结果输出“Filename is regular file”或“Filename is directory”;

(3)判断一下,执行者的身份对这个文件或目录所拥有的权限,并输出权限数据。

[leiyuxing@centos6 scripts]$ vim sh05.sh
#!/bin/bash
# program:
#     User inputs a filename, program will check the flowing:
#     1.)exist? 2.)file/directory? 3.)file permissions
# History:
# 2016/8/20 leiyuxing     First release
PATH=/bin:/sbin:/use/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
#1.让用户输入文件名,并且判断用户是否真的有输入字符串
echo -e "Please input a filename, I will check the filename's type and \
permission. \n\n"
read -p "Input a filename : " filename
test -z $filename && echo "You MUST input a filename." && exit 0
#2.判断文件是否存在,若不存在则显示信息并结束脚本
test ! -e $filename && echo "The filename '$filename' Do NOT exist" && exit 0
#3.开始判断文件类型与属性
test -f $filename && filetype="regulare file"
test -d $filename && filetype="directory"
test -r $filename && perm="readable"
test -w $filename && perm="$perm writable"
test -x $filename && perm="$perm executable"
#4.开始输出信息!
echo "The filename: $filename is a $filetype"
echo "And the permissions are : $perm"

验证结果:

[leiyuxing@centos6 scripts]$ sh sh05.sh

Please input a filename, I will check the filename's type and permission.

Input a filename : a

The filename: a is a directory

And the permissions are : readable writable executable

[leiyuxing@centos6 scripts]$ b

-bash: b: command not found

[leiyuxing@centos6 scripts]$ sh sh05.sh

Please input a filename, I will check the filename's type and permission.

Input a filename : b

The filename 'b' Do NOT exist

[leiyuxing@centos6 scripts]$ ls

a                 filename20160819  sh01.sh  sh03.sh  sh05.sh

filename20160818  filename20160820  sh02.sh  sh04.sh

4.利用判断符号[]

设置如下案例:

(1)当执行一个程序的时候,这个程序会让用户选择Y或N;

(2)如果用户输入Y或y时,就显示“OK,continue”;

(3)如果用户输入n或N时,就显示“Oh,interrupt!”;

(4)如果不是Y/y/N/n之内的其他字符,就显示”I dont’t know what your choice is”。

[leiyuxing@centos6 scripts]$ vim sh06.sh
#!/bin/bash
# program:
#     This program shows the user's choice
# History:
# 2016/8/20 leiyuxing     First release
PATH=/bin:/sbin:/use/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
 
read -p "Please input (Y/N) : " yn
[ "$yn" == "Y" -o "$yn" == "y" ] && echo "OK, continue" && exit 0
[ "$yn" == "N" -o "$yn" == "n" ] && echo "Oh, interrupt!" && exit 0
echo "I don't know what your choice is" && exit 0

验证结果:

[leiyuxing@centos6 scripts]$ sh sh06.sh

Please input (Y/N) : Y

OK, continue

[leiyuxing@centos6 scripts]$ sh sh06.sh

Please input (Y/N) : N

Oh, interrupt

[leiyuxing@centos6 scripts]$ sh sh06.sh

Please input (Y/N) : x

I don't know what your choice is

5.shell script的默认变量($0,$1...)

假设我要执行一个可以携带参数的script,执行脚本后屏幕显示如下数据:

(1)程序的文件名;

(2)共有几个参数;

(3)若参数的个数小于2则告知用户参数数量太少;

(4)全部的参数内容;

(5)第一个参数;

(6)第二个参数。                           

[leiyuxing@centos6 scripts]$ vim sh07.sh
#!/bin/bash
# program:
#     Program shows the script name, parameters...
# History:
# 2016/8/20 leiyuxing     First release
PATH=/bin:/sbin:/use/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
 
echo "The script name is ==> $0"
echo "Total parameter number is ==> $#"
[ "$#" -1t 2 ] && echo "The number of parameter is less than 2. Stop here." \
    && exit 0
echo "Your whole parameter is ==> '$@'"
echo "The 1st parameter     ==> $1"
echo "The 2nd parameter     ==> $2"

验证结果:

[leiyuxing@centos6 scripts]$ sh sh07.sh theone haha quot

The script name is ==> sh07.sh                  //文件名

Total parameter number is ==> 3                //果然有3个参数

sh07.sh: line 11: [: -1t: binary operator expected   

Your whole parameter is ==> 'theone haha quot'   //参数的内容全部

The 1st parameter     ==> theone             //第一个参数

The 2nd parameter     ==> haha              //第二个参数

6.条件判断式

(1)利用if...then

格式:

If [条件判断式]; then

  当条件判断式成立时,可以进行的命令工作内容;

fi <==将if反过来写,就成为fi,结束之意!

例:

[leiyuxing@centos6 scripts]$ vim sh08.sh
#!/bin/bash
# program:
#     This program shows the user's choice
# History:
# 2016/8/20 leiyuxing     First release
PATH=/bin:/sbin:/use/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
 
read -p "Please input (Y/N) : " yn
 
if [ "$yn" == "Y" ] || [ "$yn" == "y" ]; then
     echo "OK, continue"
     exit 0
fi
if [ "$yn" == "N" ] || [ "$yn" == "n" ]; then
     echo "Oh, interrupt!"
     exit 0
fi
echo "I don't know what your choice is" && exit 0

验证结果:

[leiyuxing@centos6 scripts]$ sh sh08.sh

Please input (Y/N) : Y

OK, continue

[leiyuxing@centos6 scripts]$ sh sh08.sh

Please input (Y/N) : N

Oh, interrupt!

[leiyuxing@centos6 scripts]$ sh sh08.sh

Please input (Y/N) : Z

I don't know what your choice i

(2)利用case...esac判断

格式:

case $变量名称 in  //关键字为case ,还有变量前有$

 “第一个变量内容”) //每个变量内容建议用双引号括起来,关键字则为小括号 )

     程序段

     ;;

 “第二个变量内容”)

     程序段

     ;;

*)               //最后一个变量内容都会用 * 来代表所有其他值

不包括第一个变量内容和第二个变量的其他程序执行段

 exit 1

 ;;

esac              //最终的case结尾!“反过来写”

例:

[leiyuxing@centos6 scripts]$ vim sh09.sh
#!/bin/bash
# program:
#     Show ”Hello" from $1... by using case ... esac
# History:
# 2016/8/20 leiyuxing     First release
PATH=/bin:/sbin:/use/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
 
case $1 in
  "hello")
     echo "Hello, how are you ?"
     ;;
  "")
    echo "You MUST input parameters,ex> {$0 someword}"
     ;;
*)
    echo "Usage $0 {hello}"
     ;;
esac

验证结果:

[leiyuxing@centos6 scripts]$ sh sh09.sh

You MUST input parameters,ex> {sh09.sh someword}

[leiyuxing@centos6 scripts]$ sh sh09.sh test

Usage sh09.sh {hello}

7.循环(loop)

(1)for...do...done(固定循环)

格式:

for var in con1 con2 con3 ...

do

      程序段

Done

例:

假设我有三种动物,分别是dog,cat,pig三种,我想每一行都输出这样:“There are dogs...”之类的字样,则可以:

[leiyuxing@centos6 scripts]$ vim sh10.sh
#!/bin/bash
# program:
#     Using for...loop to print 3 animals
# History:
# 2016/8/20 leiyuxing     First release
PATH=/bin:/sbin:/use/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
 
for animal in dog cat pig
do
      echo "There are ${animal}s..."
Done

验证结果:

[leiyuxing@centos6 scripts]$ sh sh10.sh

There are dogs...

There are cats...

There are pigs...

(2)while do done,until do done(不定循环)

格式:

while [ condition ]  //中括号内的状态就是判断式

do              //do是循环的而开始

程序段落

Done           //done是循环的结束

另一种格式:

until [ condition ]

do

   程序段落

done
示例一:
[leiyuxing@centos6 scripts]$ vim sh11.sh
#!/bin/bash
# program:
#     Repeat question until user input correct answer.
# History:
# 2016/8/20 leiyuxing     First release
PATH=/bin:/sbin:/use/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
 
while [ "$yn" != "yes" -a "$yn" != "YES" ];
do
         read -p "Please input yes/YES to stop this program: " yn
done
echo "OK! you input the correct answer."

验证结果:

[leiyuxing@centos6 scripts]$ sh sh11.sh

Please input yes/YES to stop this program: yes

OK! you input the correct answer.

[leiyuxing@centos6 scripts]$ sh sh11.sh

Please input yes/YES to stop this program: YES

OK! you input the correct answer.
示例二:
[leiyuxing@centos6 scripts]$ vim sh12.sh
#!/bin/bash
# program:
#     Repeat question until user input correct answer.
# History:
# 2016/8/20 leiyuxing     First release
PATH=/bin:/sbin:/use/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
 
until [ "$yn" == "yes" -o "$yn" == "YES" ];
do
         read -p "Please input yes/YES to stop this program: " yn
done
echo "OK! you input the correct answer."

验证结果:

[leiyuxing@centos6 scripts]$ sh sh12.sh

Please input yes/YES to stop this program: YES

OK! you input the correct answer.

[leiyuxing@centos6 scripts]$ sh sh12.sh

Please input yes/YES to stop this program: yes

OK! you input the correct answer.

8.利用function功能

格式:

Function fname () {

       程序段

}

例:

[leiyuxing@centos6 scripts]$ vim sh13.sh
#!/bin/bash
# program:
#     Use function to repeat information.
# History:
# 2016/8/20 leiyuxing     First release
PATH=/bin:/sbin:/use/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
 
function printit () {
     echo "Your choice is $1"
}
 
echo "This program will print your selection !"
case $1 in
  "one")
         printit 1
         ;;
  "two")
         printit 2
         ;;
  "three")
         printit 3
         ;;
*)
         echo "Usage $0 {one|two|three}"
         ;;
esac

验证结果:

[leiyuxing@centos6 scripts]$ sh sh13.sh one

This program will print your selection !

Your choice is 1

[leiyuxing@centos6 scripts]$ sh sh13.sh two

This program will print your selection !

Your choice is 2

[leiyuxing@centos6 scripts]$ sh sh13.sh three

This program will print your selection !

Your choice is 3

9.shell script的追踪与调试

#sh [-nvx] scripts.sh

参数:

-n:不要执行script,仅查询语法问题;

-v:在执行script前,先将script的内容输出到屏幕上;

-x:将使用到的script的内容显示到屏幕上,这是很有用的参数!

示例一:测试sh02.sh有无语法问题

[leiyuxing@centos6 scripts]$ sh -n sh02.sh

//若语法没有问题,则不会显示任何信息!

示例二:将sh10.sh的执行过程全部列出来

[leiyuxing@centos6 scripts]$ sh -x sh10.sh

+ PATH=/bin:/sbin:/use/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/home/leiyuxing/bin

+ export PATH

+ for animal in dog cat pig

+ echo 'There are dogs...'

There are dogs...

+ for animal in dog cat pig

+ echo 'There are cats...'

There are cats...

+ for animal in dog cat pig

+ echo 'There are pigs...'

There are pigs...
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的雷神

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值