shell scripts笔记(linux脚本)

前言

如果要选择运维,或者对linux系统有一定兴趣,我想一定要懂得shell scripts,因为这个东西真的很好用;为什么呢??那是因为:
1、自动化管理的重要依据
2、追踪与管理系统的重要工作
3、简单入侵侦测功能
4、连续指令单一化
5、简易的数据处理(大多数基于正则表达式处理)
6、跨平台支持与学习历程较短(几乎所有的 Unix Like 上面都可以跑 shell script ,连 MS Windows 系列也有相关的 script 仿真器可以用)

编写第一个shell

在 shell script 的撰写中还需要用到下面的注意事项:

  1. 指令的执行是从上而下、从左而右的分析与执行;
  2. 指令的下达就如同第四章内提到的: 指令、选项与参数间的多个空白都会被忽略掉;
  3. 空白行也将被忽略掉,并且 [tab] 按键所推开的空白同样视为空白键;
  4. 如果读取到一个 Enter 符号 ( CR ) ,就尝试开始执行该行 (或该串) 命令;
  5. 至于如果一行的内容太多,则可以使用 “ [Enter] ” 来延伸至下一行;
  6. “ # ” 可做为注解!任何加在 # 后面的数据将全部被视为注解文字而被忽略!

如何执行shell文件?通过一下几种方法:
直接指令下达: shell.sh 文件必须要具备可读与可执行 ( rx ) 的权限,然后:
1、绝对路径:使用 /home/dmtsai/shell.sh 来下达指令;
2、相对路径:假设工作目录在 /home/dmtsai/ ,则使用 ./shell.sh 来执行
3、变量 “PATH” 功能:将 shell.sh 放在 PATH 指定的目录内,例如: ~/bin/
以 bash 程序来执行:通过 “ bash shell.sh ” 或 “ sh shell.sh ” 来执行

第一个shell例子:
[dmtsai@study ~]$ mkdir bin; cd bin
[dmtsai@study bin]$ vim hello.sh
#!/bin/bash
#Program:
#This program shows “Hello World!” in your screen.
#History:
#2015/07/16 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo -e “Hello World! \a \n”
exit 0

1. 第一行 #!/bin/bash 在宣告这个 script 使用的 shell 名称:
因为我们使用的是 bash ,所以,必须要以 “ #!/bin/bash ” 来宣告这个文件内的语法使用 bash 的语法!那么当这个程序被执行时,他就能够载入 bash 的相关环境配置文件 (一般来说就是 non-login shell 的~/.bashrc ), 并且执行 bash 来使我们下面的指令能够执行!这很重要的!

2. 程序内容的说明:
整个 script 当中,除了第一行的 “ #! ” 是用来宣告 shell 的之外,其他的 # 都是 “ 注解 ” 用途! 所以上面的程序当中,第二行以下就是用来说明整个程序的基本数据。一般来说, 建议你一定要养成说明该 script 的:

  1. 内容与功能;
  2. 版本信息;
  3. 作者与联络方式;
  4. 创建日期;
  5. 历史纪录 等等。这将有助于未来程序的改写与 debug 呢!

3. 主要环境变量的宣告:
建议务必要将一些重要的环境变量设置好, PATH 与 LANG (如果有使用到输出相关的信息时) 是当中最重要的! 如此一来,则可让我们这支程序在进行时,可以直接下达一些外部指令,而不必写绝对路径呢!比较方便啦!

4. 主要程序部分
就将主要的程序写好即可!在这个例子当中,就是 echo 那一行啦!

5. 执行成果告知 (定义回传值)
一个指令的执行成功与否,可以使用 $? 这个变量来观察~ 那么我们也可以利用 exit 这个指令来让程序中断,并且回传一个数值给系统。 在这个例子当中使用 exit 0 ,这代表离开 script 并且回传一个 0 给系统。

另外,也可以利用: “chmod a+x hello.sh或者 ./hello.sh” 来执行这个 script !

一定要养成良好的 script 撰写习惯,在每个 script 的文件开始处记录好:
script 的功能;
script 的版本信息;
script 的作者与联络方式;
script 的版权宣告方式;
script 的 History (历史纪录);
script 内较特殊的指令,使用 “ 绝对路径 ” 的方式来下达;
script 运行时需要的环境变量预先宣告与设置。

简单的范例:
以 read 指令的用途,撰写一个 script ,他可以让使用者输入: 1. first name 与 2. last name , 最后并且在屏幕上显示: “Your full name is: ” 的内容:
[dmtsai@study bin]$ vim showname.sh
#!/bin/bash
#Program:
#User inputs his first name and last name. Program shows his full name.
#History:
#2015/07/16 VBird First release
PATH=/bin:/sbin:/usr/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}” # 结果由屏幕输出

随日期变化:利用 date 进行文件的创建
[dmtsai@study bin]$ vim create_3_filename.sh
#!/bin/bash
#Program:
#Program creates three files, which named by user’s input and date command.
#History:
#2015/07/16 VBird First release
PATH=/bin:/sbin:/usr/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: " fileuser # 提示使用者输入
#2. 为了避免使用者随意按 Enter ,利用变量功能分析文件名是否有设置?
filename=KaTeX parse error: Expected 'EOF', got '#' at position 24: …r:-"filename"} #̲ 开始判断有否配置文件名 #3… ( date --date=‘2 days ago’ +%Y%m%d ) # 前两天的日期
date2=$ ( date --date=‘1 days ago’ +%Y%m%d ) # 前一天的日期
date3=$ ( date +%Y%m%d ) # 今天的日期
file1= f i l e n a m e {filename} {date1} # 下面三行在配置文件名
file2= f i l e n a m e {filename} {date2}
file3= f i l e n a m e {filename} {date3}
#4.将文件名创建吧!
touch “KaTeX parse error: Expected 'EOF', got '#' at position 10: {file1}" #̲ 下面三行在创建文件 touc…{file2}”
touch “${file3}”

数值运算:简单的加减乘除
[dmtsai@study bin]$ vim multiplying.sh
#!/bin/bash
#Program:
#User inputs 2 integer numbers; program will cross these two numbers.
#History:
#2015/07/16 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo -e “You SHOULD input 2 numbers, I will multiplying them! \n”
read -p "first number: " firstnu
read -p "second number: " secnu
total=$ (( f i r s t n u {firstnu}* {secnu} ))
echo -e “\nThe result of ${firstnu} x ${secnu} is ==> ${total}”

数值运算:通过 bc 计算 pi
[dmtsai@study bin]$ vim cal_pi.sh
#!/bin/bash
#Program:
#User input a scale number to calculate pi number.
#History:
#2015/07/16 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo -e “This program will calculate pi value. \n”
echo -e “You should input a float number to calculate pi value.\n”
read -p "The scale number ( 10~10000 ) ? " checking
num=KaTeX parse error: Expected 'EOF', got '#' at position 18: …hecking:-"10"} #̲ 开始判断有否有输入数值 ec…{num}; 4*a ( 1 ) " | bc -lq

shell script 的执行方式差异 ( source, sh script, ./script )

利用直接执行的方式来执行 script,使用这种执行方式时, 其实 script 是在子程序的 bash 内执行的! 当子程序完成后,在子程序内的各项变量或动作将会结束而不会传回到父程序中

利用 source 来执行脚本:在父程序中执行

使用判断式

利用 test 指令的测试功能
在这里插入图片描述
在这里插入图片描述

判断一下,让使用者输入一个文件名,我们判断:

  1. 这个文件是否存在,若不存在则给予一个 “Filename does not exist” 的讯息,并中断程序;
  2. 若这个文件存在,则判断他是个文件或目录,结果输出 “Filename is regular file” 或 “Filename is directory”
  3. 判断一下,执行者的身份对这个文件或目录所拥有的权限,并输出权限数据!
    执行这个脚本后,他会依据你输入的文件名来进行检查喔!先看是否存在,再看为文件或目录类型,最后判断权限。

[dmtsai@study bin]$ vim file_perm.sh
#!/bin/bash
#Program:
#User input a filename, program will check the flowing:
#1. ) exist? 2. ) file/directory? 3. ) file permissions
#History:
#2015/07/16 VBird First release
PATH=/bin:/sbin:/usr/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 KaTeX parse error: Expected 'EOF', got '&' at position 12: {filename} &̲& echo "The fil…{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 KaTeX parse error: Expected 'EOF', got '&' at position 12: {filename} &̲& perm="{perm} writable"
test -x KaTeX parse error: Expected 'EOF', got '&' at position 12: {filename} &̲& perm="{perm} executable"
#4. 开始输出信息!
echo “The filename: ${filename} is a ${filetype}”
echo “And the permissions for you are : ${perm}”

利用判断符号 [ ]

如果要知道 H O M E [ d m t s a i @ s t u d y   ] {HOME} 这个变量是否为空的,可以这样做: [dmtsai@study ~] [ -z “${HOME}” ] ; echo $?

如果要在 bash 的语法当中使用中括号作为 shell 的判断式时,必须要注意中括号的两端需要有空白字符来分隔喔! 假设我空白键使用 “□” 符号来表示,那么,在这些地方你都需要有
空白键:
[ “ H O M E " = = " HOME" == " MAIL” ]
[□" H O M E " = = " HOME"□==□" MAIL"□]
↑ ↑ ↑ ↑

使用中括号的判断来做一个小案例好了,案例设置如下:

  1. 当执行一个程序的时候,这个程序会让使用者选择 Y 或 N ,
  2. 如果使用者输入 Y 或 y 时,就显示 “ OK, continue ”
  3. 如果使用者输入 n 或 N 时,就显示 “ Oh, interrupt ! ”

如果不是 Y/y/N/n 之内的其他字符,就显示 “ I don’t know what your choice is ”
利用中括号、 && 与 || 来继续吧!
[dmtsai@study bin]$ vim ans_yn.sh
#!/bin/bash
#Program:
#This program shows the user’s choice
#History:
#2015/07/16 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
read -p "Please input ( Y/N ) : " yn
[ “ y n " = = " Y " o " {yn}" == "Y" -o " {yn}” == “y” ] && echo “OK, continue” && exit 0
[ “ y n " = = " N " o " {yn}" == "N" -o " {yn}” == “n” ] && echo “Oh, interrupt!” && exit 0
echo “I don’t know what your choice is” && exit 0

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

如果通过指令后面接参数, 那么一个指令就能够处理完毕而
不需要手动再次输入一些变量行为!这样下达指令会比较简单方便啦!
script 是怎么达成这个功能的呢?其实 script 针对参数已经有设置好一些变量名称了!对应如下:
/path/to/scriptname opt1 opt2 opt3 opt4
$0 $1 $2 $3 $4
执行的脚本文件名为 $0 这个变量,第一个接的参数就是 $1 啊~ 所以,只要我们在 script 里面善用 $1 的话,就可以很简单的立即下达某些指令功能了!除了这些数字的变量之外, 我们还有一些较为特殊的变量可以在 script 内使用来调用这些参数!
$# :代表后接的参数 “ 个数 ” ,以上表为例这里显示为 “ 4 ” ;
$@ :代表 “ “$1” “$2” “$3” “$4” ” 之意,每个变量是独立的(用双引号括起来);
$* :代表 “ “$1c$2c$3c$4” ” ,其中 c 为分隔字符,默认为空白键, 所以本例中代表 “ “$1 $2 $3 $4” ” 之意。

执行一个可以携带参数的 script ,执行该脚本后屏幕会显示如下的数据:
程序的文件名为何?
共有几个参数?
若参数的个数小于 2 则告知使用者参数数量太少
全部的参数内容为何?
第一个参数为何?
第二个参数为何?

[dmtsai@study bin]$ vim how_paras.sh
#!/bin/bash
#Program:
#Program shows the script name, parameters…
#History:
#2015/07/16 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo “The script name is ==> ${0}”
echo “Total parameter number is ==> KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲" [ "#” -lt 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}”

执行结果如下:
[dmtsai@study bin]$ sh how_paras.sh theone haha quot
The script name is ==> how_paras.sh <==文件名
Total parameter number is ==> 3 <==果然有三个参数
Your whole parameter is ==> ‘theone haha quot’ <==参数的内容全部
The 1st parameter ==> theone <==第一个参数
The 2nd parameter ==> haha <==第二个参数

shift :造成参数变量号码偏移

我们将 how_paras.sh 的内容稍作变化一下,用来显示每次偏移后参数的变化情况:
[dmtsai@study bin]$ vim shift_paras.sh
#!/bin/bash
#Program:
#Program shows the effect of shift function.
#History:
#2009/02/17 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo “Total parameter number is ==> KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲" echo "Your wh…@’”
shift # 进行第一次“一个变量的 shift ”
echo “Total parameter number is ==> KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲" echo "Your wh…@’”
shift 3 # 进行第二次“三个变量的 shift ”
echo “Total parameter number is ==> KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲" echo "Your wh…@’”

执行成果如下:
[dmtsai@study bin]$ sh shift_paras.sh one two three four five six <==给予六个参数
Total parameter number is ==> 6 <==最原始的参数变量情况
Your whole parameter is ==> ‘one two three four five six’
Total parameter number is ==> 5 <==第一次偏移,看下面发现第一个 one 不见了
Your whole parameter is ==> ‘two three four five six’
Total parameter number is ==> 2 <==第二次偏移掉三个,two three four 不见了
Your whole parameter is ==> ‘five six’

结语

这些都是shell的基本操作用法,后面会利用一篇文章介绍条件语句这些。

发布了19 篇原创文章 · 获赞 0 · 访问量 1399

猜你喜欢

转载自blog.csdn.net/qq_22356995/article/details/104209650
今日推荐