Linux Shell Script的基础知识
来源:互联网 发布:易吧进销存软件下载 编辑:程序博客网 时间:2024/05/22 03:49
Shell Script 就像是早期DOS年代的批处理文件(.bat), 执行一个档案可以一次执行多个命令
Shell Script 提供数组,循环,条件,逻辑判断等重要的功能,可以直接以Shell来撰写程序
而不必使用类似C程序语言等传统程序撰写的语法,由于是利用Shell与相关工具指令,所以不需要编译
即可执行,且拥有不错的除错(debug)工具
Shell Script可以帮助:
1 自动化管理的重要依据,写个简单的script程序可以帮你每日自动处理分析登录档,追踪流量,监控用户使用主机状态
以上等等的操作,就需要一个良好的Shell script来帮忙的
2 追踪与管理系统的重要工作,Linux系统的服务启动的接口是在 /etc/init.d这个目录下,目录下的所有档案都是
scripts,另外包括开机过程都是利用shell script来帮忙搜索系统的相关设定数据,然后再代入各个服务的设定参数
3 数据入侵检测功能 , 系统中大多将异状记录在系统记录器,也就是我们常常提到的【系统注册表档】,固定的时间
去分析系统注册表档,若有问题,则立刻通知管理员,或者立刻加强防火墙的设定规则。或者判断该封包尝试几次还是
联机失败之后,就予以抵挡住该IP之类的举动,我们可以将以上的操作写入一个shell script去分析.
4 连续指令单一化,script最简单的功能就是帮我们把一大串的指令汇整在一个档案里面,而直接执行该档案就可以
执行那一串指令段了
5 简易的数据处理,shell script功能强大,可以对数据的比对,文字数据的处理,撰写方便,速度又快
6 跨平台支持不学习历程较短 shell script的语法是相当有亲和力的,而不是机器码,较容易学习
不过 虽然shell script号称是程序,但实际上,shell script处理数据的速度不太快的,shell script用的是外部的指令
与bash shell的一些默认工具,常常会去呼叫外部函数库,所以不适宜处理大量数值运算上,因为shell scripts的
速度较慢,且使用的CPU的资源较多,造成主机资源的分配不良,不过我们通常利用shell script来处理服务器的侦测
不会有大量的运算的需求,所以没事.
Shell Script 的撰写中需要用到底下的注意事项
1 读取到一个Enter符号(CR) , 就尝试开始执行该行(或该串)命令
2 如果一行内容太多,可以使用【\[enter]】来延伸至下一行
3 #号可做为批注,任何在#号后面的资料将全部被视为批注文字而被忽略
直接指令下达:
shell.sh 档案必须具备可读可执行的权限
绝对路径:使用 /home/dmtsai/shell.sh
相对路径:./shell.sh
变量【path】功能 : 将shell.sh 放在PATH指定的目录内,例如:~/bin/
以 bash 程序来执行:透过『 bash shell.sh 』戒『 sh shell.sh 』来执行
可以使用sh的参数 -n或-x来检查与追踪shell.sh 的语法是否正确
shell script的内容大致分为
1.第一行 #!/bin/bash在宣告这个scripts使用的shell名称
当文件被执行时,会加载bash的相关环境配置文件
(一般来说就是non-login shell 的~/.bashrc),并且执行bash来使我们底下的指令能够执行,如果没有这行
可能造成程序无法判断使用什么样的shell来执行
2.第二行 程序内容的说明:
整个script当中,除了第一行的【#!】是用来宣告shell的之外,第二行以下用来说明整个程序的基本数据
1 内容和功能 2版本信息 3作者和联络方式 4 建档日期 5 历史记录
3.主要环境变量的宣告:
建议务必要将一些重要的环境变量设定好,PATH与LANG(如果有使用到输出相关的信息)是当中最重要的
可以直接下达一些外部指令,而不必写绝对路径比较好
4 主要程序部分
就将主要的程序写好即可
5 执行成果告知
可以使用$?这个变量来观察,也可以使用exit这个命令让程序中断,并且回传一个值给系统,例如exit 0
代表回传了一个0给系统,所以当执行完这个script后,若接着下达echo $? 则可得到0这个值,exit n(n是个数字)
我们可以根据这个n来自定义错误讯息,让这支程序变得更加smart
当内容执行程序中包含printf或者用echo -e接着那些特殊的按键也可以听到『咚』的一声
编写Shell Script需要记录
script的版本信息
script的作者和联系方式
script的版权宣告方式
script的History历史记录
script内较特殊的指令,需要使用绝对路径的方式来下达
script运作时需要的环境变量预先宣告和设定
最好使用【tab】按键的空格向后推,最好使用vim,可以在编辑的时候发现错误
编写对谈式脚本:变量内容由用户决定
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin 声明PATH这个环境变量
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进行档案的建立
创建 filename_20090212, filename_20090213, filename_20090214
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
# 1. 讥使用者输入文件名,幵叏得 fileuser 这个发量;
read -p "Please input your filename: " fileuser
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"
简单的加减乘除
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 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"
declare -i total=$firstnu*$secnu 』 也可以使用这个方式来运行!
var=$((运算内容))
脚本除了使用之前的几种方式执行,还可以使用souce和小数点 (.)来执行
无论使用哪种方式运行,该script都会使用一个新的bash环境来执行脚本内的指令,
其实script是在子程序的bash内执行的,不使用export的话,当子程序完成后,在子程序中的各项变量
或动作将会结束而不会回传到父程序中。
而加上export的话,执行echo $firstname $lastname 这两个变量在父程序的bash中还是存在的
利用 source 来执行脚本:在父程序中执行
因为source对script的执行方式会在父程序中执行的,因此各项动作都会在原本的bash内生效
,这也是为啥不注销系统而要让某些写入~/.bashrc的设定生效时,需要使用source ~/.bashrc 而不能使用 bash ~/.bashrc
善用表达式
长长通过$?的返回值来判断后续的指令是否进行执行,但是有更简单的可以进行条件判断,那就是【test】这个指令
检查 /dmtsai 是否存在时,test -e /dmtsai
test -e /dmtsai && echo "exist" || echo "Not exist" 表示存在显示前者,不存在显示后者
test的常用参数
关亍某个档名的『文件类型』刞断,如 test -e filename 表示存在否
-e 该『档名』是否存在?(常用)
-f 该『档名』是否存在且为档案(file)?(常用)
-d 该『文件名』是否存在且为目录(directory)?(常用)
-b 该『档名』是否存在且为一个 block device 装置? -
c 该『档名』是否存在且为一个 character device 装置?
-S 该『档名』是否存在且为一个 Socket 档案?
-p 该『档名』是否存在且为一个 FIFO (pipe) 档案?
-L 该『档名』是否存在且为一个连结档?
2. 关亍档案的权限侦测,如 test -r filename 表示可读否 (但 root 权限常有例外)
-r 侦测该档名是否存在且具有『可读』的权限?
-w 侦测该档名是否存在且具有『可写』的权限?
-x 侦测该档名是否存在且具有『可执行』的权限?
-u 侦测该文件名是否存在且具有『SUID』的属性?
-g 侦测该文件名是否存在且具有『SGID』的属性?
-k 侦测该文件名是否存在且具有『Sticky bit』的属性?
-s 侦测该档名是否存在且为『非穸白档案』?
3. 两个档案之间的比较,如: test file1 -nt file2
曼联转会-nt (newer than)判断 file1 是否比 file2 新
-ot (older than)判断 file1 是否比 file2 旧
-ef 判断 file1 不 file2 是否为同一档案,可用在判断 hard link 的刞定上。 主要意义在判定,两个档案是否均指向同一个 inode 哩!
4. 关亍两个整数之间的判定,例如 test n1 -eq n2
-eq 两数值相等 (equal)
-ne 两数值丌等 (not equal)
-gt n1 大亍 n2 (greater than)
-lt n1 小亍 n2 (less than)
-ge n1 大亍等亍 n2 (greater than or equal)
-le n1 小亍等亍 n2 (less than or equal)
5. 判定字符串的数据
test -z string 判定字符串是否为 0 ?若 string 为空字符串,则为 true
test -n string 判定字符串是否非为 0 ?若 string 为空字符串,则为 false。 注: -n 亦可省略
test str1 = str2 判定 str1 是否等亍 str2 ,若相等,则回传 true
test str1 != str2 判定 str1 是否不等亍 str2 ,若相等,则回传 false
6. 多重条件刞定,例如: test -r filename -a -x filename
-a (and)两状况同时成立!例如 test -r file -a -x file,则 file 同时具有 r 不 x 权限时,才回传 true。
-o (or)两状况任何一个成立!例如 test -r file -o -x file,则 file 具有 r 戒 x 权限时,就可回传 true。
! 反相状态,如 test ! -x file ,当 file 不具有 x 时,回传 true
再来写一个脚本,条件:
1. 这个档案是否存在,若不存在则给予一个『Filename does not exist』的讯息,并中断程序;
2. 若这个档案存在,则判断他是个档案戒目录,结果输出『Filename is regular file』戒
『Filename is directory』
3. 刞断一下,执行者的身份对这个档案戒目录所拥有的权限,并输出权限数据!
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 $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"
利用判断符号 [ ]
以上这个符号用来进行数据的判断的,如果我想要知道$HOME这个变量是否为空的,可以这样做
[ -z "$HOME" ] ; echo $? 中括号的两端还有等号的两边需要有空格符来分隔
还要注意一个等号代表变量的设定,而两个等号代表逻辑的判断
在中括号内的变量,最好都以双引号括号起来;
在中括号内的常数,最好都以单或双引号括号起来
Shell Script的默认变数
例如 : /etc/init.d/syslog restart
如果指令后面接参数,那么一个指令就能够处理完毕而不需要手动再次输入一些变量行为
script 针对参数已经设定好一些变量名称了
例如:/path/to/scriptname opt1 opt2 opt3 opt4
$0 $1 $2 $3 $4
执行脚本的档名是$0这个变量 第一个接的参数是$1
$# 代表后接的参数【个数】,以上表为例这里显示为4
$@ 代表【"$1" "$2" "$3" "$4"】之意,这个变量是独立的(用双引号括起来)
$* 代表 【"$1 $2 $3 $4"】
shift 命令的作用是造成参数变量号码偏移
sh sh08.sh one two three four five six <==给予六个参数
shift 1 则是把第一个变量给去掉了
shift 3 则是把第二到第四的变量给去掉了
最后只剩下变量 5和 6了
条件判断式
if ......elif.......else,
case $变量 in
function功能,为了处理共通的模块,方法中的$1和shell script中的$1 是不同的,前者是调用方法时传的参数
而后者是调用脚本时传递的参数
loop 不定循环
while do done , until do done 不定循环
while [ condition ] <==中括号内的状态就是判断式
do
<==do 是循环的开始!
程序段落
done
<==done 是循环的结束
当condition条件成立时,就进行循环,直到condition的条件不成立才停止
还有一种不定循环的方式
until [ condition ]
do
程序段落
done
这种判断表示,当condition条件成立时,就终止循环,否则就持续进行循环的程序段
for...do...done 固定循环
for animal in dog cat elephant
do
echo "There are ${animal}s.... "
done
for...do...done 的另一种写法
for (( 初始值; 限制值; 执行步阶 ))
do
程序段
done
shell script的追踪与debug
选项与参数:
-n :不要执行 script,仅查询语法的问题;
-v :再执行 sccript 前,先将 scripts 的内容输出到屏幕上;
-x :将使用到的 script 内容显示到屏幕上,这是很有用的参数!
- Linux Shell Script的基础知识
- shell script基础知识概要
- Linux的Shell Script学习
- Linux基础知识整理[7]——Shell script
- 【Unix/Linux.Shell Script】Shell & Shell Script
- 一个修改配置文件的linux shell script
- Linux学习-shell script 的默认变量
- LINUX shell script 打包
- linux shell script 入门
- linux shell script 函式
- linux shell script
- Linux shell script
- [linux]shell script 随记
- Linux Shell Script Study
- FTP linux shell script
- linux-shell script
- Linux Shell Script目录
- Linux shell script
- Web服务中的Session对象
- 有关QT表格
- USACO 1.3.2 Barn Repair
- JavaScript异常机制
- hdu4486 Pen Counts 简单啊。。。。。
- Linux Shell Script的基础知识
- Linux内核2.6.34.7编译不带O2优化的Linux内核
- 内存对齐 alignment
- Interleaving String
- C#窗口任意位置拖动
- spring security
- 在webservice中使用session
- this指针
- 数据库密码忘记之后 - Oracle, DB2, SqlServer, MySql