SHELL SCRIPTING 教学与心得.docx_第1页
SHELL SCRIPTING 教学与心得.docx_第2页
SHELL SCRIPTING 教学与心得.docx_第3页
SHELL SCRIPTING 教学与心得.docx_第4页
SHELL SCRIPTING 教学与心得.docx_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

SHELL SCRIPTING 教学与心得 20版权声明 前言 基本观念与操作 Shell Script 概论 变量定义 shell的判断式 循环 for while loop shell script的数组 (array) 处理 sed 字符串编辑器 awk 结构化的数据处理工具 范例 (未完成) 旧版shell文件1 旧版shell文件2 旧版perl文件1 前言底下的教学与心得分享是假设你已经有着基本的UNIX or Linux观念与技巧, 同时我们利用Linux预设提供的bash shell来操作, 例如 :- login in- basic commands (ls, mkdir.etc)- how to move around the system(with cd command)- 使用 vi同时读者可能也必须了解基本程控, 例如 : 变量定义, 流程控制loop 等.另外, shell script的技巧基本上是不分UNIX or Linux的, 所以学会shell script是很吃香的喔! 作为一个系统管理者, 除了在系统管理上需要熟悉那些工具, 档案的位置等等外, shell script绝对是不可或缺的能力.同时, 也希望如果你觉得这个对你有帮助, 请给我一个email帮我加油 !基本观念与操作 建立第一个shell script $ pwd/home/xfish/bin$ ls myscriptmyscript2$ cat myscriptls -aF$ myscriptbash: ./myscript: Permission denied$ chmod +x myscript$ myscript./ ./ myscript* myscript2*shell script其实就是一个很简单的文本文件, 档案里面有着可以操作与控制相关动作与命令, 同时它必须具备能够执行的能力,在UNIX与Linux环境下, 也就是必须有 +x 的属性 上面是一个很简单的shell script, 简单地列出目前目录下的档案.同时由于Linux/UNIX底下有多种shell的编译程序, 我们也可以在该script中的第一行来指定利用特定的编译程序执行, 例如我们可以指定 : #!/bin/bash 使用echo命令echo是用来显示输出的命令, 用几个范例做个解释, 后面的章节将会看到常常利用echo来做些输出的动作 : $ echo a b ca b c$ echo a b ca b c$ echo $0-bash (说明, 这个会依照你使用的shell不同而改变)同时echo还能搭配以下特殊符号来控制特别输出 : aalert, beeps the bellbbackspace charactercsuppresses the new linefformfeed characternnew-linerreturn characterttab charactervvertical tab charactersingle backslash character起始档案 startup files 跟以往的DOS相同, 使用者登入后, 系统的shell在读取完系统的配置文件后(/etc/profile), 会自动读取使用者shell, 例如 : $HOME/.bashrc 或者 $HOME/.profile因此, 若有一些需要使用者登入后就执行或者设定的动作, 可以在这两个档案作设定的起始档案命令区隔 若有同时两个命令要执行, 必须使用 ; 来区隔 $ date who (错误)date: bad conversion$ date ; who (正确)Tue Aug 25 15:38:24 2005xfishtty00Aug 25 15:30rootttyp1Aug 25 10:00$ cd bin ; pwd/home/xfish/bin$ cd . ; pwd/home/xfishGrouping 命令 利用( ) 来整合命令, 例如 : $ pwd/home/xfish$ ( cd /bin ; pwd )/bin$ pwd/home/xfish$ ls -l /usr/bin ; ls -l /usr/share | wc -l这样会列出 /usr/bin 与/usr/share 目录下的档案, 但是事实上我们只要算算这总共有多少命令, 因此我们可以利用下面的命令取代 :$ (ls -l /usr/bin ; ls -l /usr/share ) | wc -l185$Shell Script 概论这一章, 我们会谈到包括一些使用shell script的基本方法, 主要会提到 : Aliases 别名 Here Documents 可以说是一种内嵌的文件 Job Control 工作控制 Aliases 别名直接在命令提示符号下 : alias 命令 , 你就可以看到目前定义的 alias.而alias就是常常用来把一大串命令缩写的常用技巧.比如说我喜欢ls的时候加上ls -F选项, 同时我希望打ls时候预设就带入 -F参数, 就可以利用 : $ alias ls=ls -F 来达到你的目的多看几个例子 :$ alias lf=/usr/bin/ls -CaF $ alias rm=echo $ rm /tmp/junk /tmp/junk Here Documents 一种内嵌于shell script的技巧, 直接用例子说明 : $ cat phone #!/bin/bash grep -i $1 /dev/nullthen echo found $1else echo didnt find $1fi$ myscript5 xfishfound xfish$ myscript5 ABAaadidnt find ABAaa那如果多重式的if-then-else要怎么写呢? 我们再以刚刚的例子来变化.$ cat myscript6#!/bin/shif grep $1 /etc/passwd /dev/nullthen echo found $1 in /etc/passwdelif grep $1 /etc/greoup /dev/nullthen echo found $1 in /etc/groupelse echo didnt find $1fi$ myscript6 otherfound other in /etc/group$ myscript6 AabcdBdidnt find AabcdB关于if-then-else的写法, 我自己通常的习惯, 都会将 then往上提, 这样的写法 可以让程序行数少一点, 比较美观一点. 参考看看.$ cat myscript6#!/bin/shif grep $1 /etc/passwd /dev/null; then echo found $1 in /etc/passwdelif grep $1 /etc/group /dev/null; then echo found $1 in /etc/groupelse echo didnt find $1fiTesting 判断式Testing 判断式通常与if-then-else一起互用, 以便发挥其效果.先从一个最简单的例子看起 :$ cat myscript7#!/bin/shif -f /etc/passwd ; then echo /etc/passwd is a fileelse echo PANIC : /etc/passwd is not a file!fi先说明一下 -f /etc/passwd 这个最重要的部份, 里面就是判断式, 而这里是判断 /etc/passwd 是不是一个 file ?由结果来看看是执行 then 下面的叙述, 或者执行 else 的叙述.同时很重要一点是 底下这些叙述都是不正确的叙述, 会有错误产生喔 :-f /etc/passwd -f 连在一起 -f /etc/passwdpasswd 连在一起 -f/etc/passwd -f与/etc/passwd连在一起所以利用 我们可以做出以下这些判断, 这些也都很常用喔 !testtrue if . string1 = string2 string1 and string2 are equal string1 != string2 string1 and string2 are not equal string1 string2 string1 is lexically greater than string2 (e.g. b is greater than a) -z string string is zero (e.g. a empty string) -n string string is nonzero (e.g. a VAR string) -e file file exists -f file file is a file -d file file is a directory -c file file is a character device -b file file is a block device -p file file is a named pipe -s file file is not empty -k file files sticky bit is set -S file file is a socket -L file file is a symbolic link -r file file is readable by user -w file file is writeable by user -x file file is executeable by user -O file file is owner by user -G file file is group owned by a greoup -u file file has its set user ID bit set -g file file has its group user ID bit set file1 -nt file2 file1 is newer than file2 file1 -ot file2 file1 is older than file2 file -ef file2 file1 is another name for file2 n1 -eq n2 true if integer n1 = integer n2 n1 -ne n2 true if integer n1 n2 n1 -gt n2 true if n1 n2 n1 -ge n2 true if n1 = n2 n1 -lt n2 true if n1 n2 n1 -le n2 true if n1 $filename does not exist read -r filenamedoneecho $filename name OK$ myloop1/etc/password- /etc/password does not exist/etc/groups- /etc/groups does not exist/etc/group/etc/group name OK$说明 :执行后, 会等待使用者输入一个档名, 接着会检查该输入字符串是否真为一个档案 (利用 -f 判断), 若是则跳出 while loop 并且印出 檔名 name OK反之, 则印出 - 檔名 does not exist , 并继续要求使用者输入.until 循环同 while , until 的功用与语法很类似, 请参考$ cat myloop2#!/bin/shuntil who | grep dino /dev/null; do sleep 10doneecho dino has logged in$ myloop2 &2 9281$ dino has logged in我们再用一个例子来让循环多点变化 :$ cat myloop3#!/bin/shi=1while $i != 7 ; do echo $i i=expr $i + 1done$ myloop3123456$这个范例 我想就不用怎么说明了, 不过利用这个范例跟大家分享一下, 我常常用来做倒数计时的一个循环 :#!/bin/shinterval=10total=1while $total -le 5 ; do i=1 while $i -le $interval ; do echo -e $total / $i / $interval rc sleep 1 i=expr $i + 1 done total=expr $total + 1done请大家试试 就可以知道 这大概是什么用的, 不过有时候echo 的语法 似乎在各种不同的 shell (e.g. /bin/sh, /bin/bash)之间 并不完全相同 这可能要花一点点时间去确认的.for 循环继续谈到 for 循环, for 循环通常使用在比较有明确范围的情况.例如 :$ cat myloop4#!/bin/shfor foo in *; do if -f $foo ; then echo $foo is a file elif -d $foo ; then echo $foo is a directory else echo $foo is not a file, nor directory fidone$ myloop4snake.txt is a filetab.txt is a filetinrc.txt is a filetmp is a directorytmp1 is a fileshell script的数组 (array) 处理 数组(array)的用途应该不用特别说明, 就是让你用变量更方便, 用来处理相类型的数据更方便.所以, 用实例说明比较快:比如说, 我今天要寄信给三个管理者, 没有数组的时候, 可以这样写:#!/bin/bashadmin1=admin2=admin3=mail -s Log file $admin1 $mylog # $mylog 随便定义mail -s Log file $admin2 $mylog # $mylog 随便定义mail -s Log file $admin3 $mylog # $mylog 随便定义这是脚踏实地的写法, 但是比较弹性的作法:#!/bin/bashadmins=( )for name in $admins; do mail -s Log file $name $mylogdone或者这样的 array 存取也是一样的:#!/bin/bashadmins=( )for (i=0; i$#admins; i+); do #请注意 ( ) 双层括号 mail -s Log file $admins$i file2将 filename 档案内的 xfish 字符串那一行删除sed /xfish/d filename同样, 若是要将修改过的档案变成一个新档案, 可以这样做 :cat file1 | sed /xfish/d file2指定哪一行,将之删除sed 4d filename这里是指定第四行 删除将filename的第一行到第几行,将之删除sed 1,4d filename这里是指定第一行到第四行 删除将filename的第一行到第五行印出sed -n 1,5p filename将 file 档案内的出现 xfish 字符串的那一行单独写到 file2 内sed -n /xfish/w file2 file通配符的使用,将 file 档案内的 xfis? 哪一行写到 file2 内sed /xfis./w file2 file万用字符串的使用,将 file 档案内的 xfis* 哪一行写到 file2 内sed /xfis*/w file2 file选定字符的使用,将 file 档案内的 xfisabcd 哪一行写到 file2 内sed /xfisabcd/w file2 file特别符号的取消,利用 /sed s/ file一行的起头的取代,将 file 档案的每一行起头都加上 Hi.sed s/Hi. / file一行的结尾的取代,将 file 档案的每一行结尾都加上 Hi.sed s/$/Hi. / file多重条件的指定,利用 -e 选项sed -e s/Giga/GigaRama/ -e s/Hi./ file awk 结构化的数据处理工具 (未完成)范例 (未完成)这些部分都是我自己写的例子, 可能不完全正确, 或者说还有很多可以改进的地方, 如果有任何建议, 请给我email.还有一些部份是直接从网络上收集的, 挑几个作一些参考.另外, 若你有什么好的script, 愿意一起放进来, 我都很欢迎喔.:)把目录下大写的文件名 修改成小写的文件名#!/bin/shfor file in A-Z*; do echo processing $file mv $file echo $file | tr A-Z a-zdone用shell script计算经过时间, 时间的加减法, 比较时间方法这是从别人那边学来的, 因为shell script可以使用的函数不够多,但是透过这样的方式就可以来计算经过的时间:# 取得开始时间 这个也可以用 date +%s 取代before=date +%s# 这里就是要系统去作什么事情的命令sleep 125# 举得命令结束的时间after=date +%selapsed=echo $after - $before | bchours=echo elapsed / 3600 | bcelapsed=echo $elapsed - $hours * 3600 | bcminutes=echo $elapsed / 60 | bcseconds=echo $elapsed - $minutes * 60 | bcecho it takes : $hours:$minutes:$seconds# 这个例子会 - 0:2:5修改檔名, 把 *.htm 修改成 *.html 这个在DOS下可能用一个 rename 就可以解决了, 但是很抱歉UNIX/Linux上面可不行. 所以 shell script 就可以帮上忙了.#!/bin/shfor i in *.htm ; do echo processing $i mv $i basename $i .htm.htmldone输入 mycmd f1 f2 f3 f4 . fn 把每个 f* 复制成 f*.bak 利用 while 与 shift 的技巧 :#!/bin/shwhile $# -gt 0 ; do # 批注 把 echo 拿掉 就真的变成命令了. # 这里只有 echo 出来 并没真正执行 echo cp $1 $1.bak shiftdone系统登入后 提示选单 选择连上 PTT BBS (2007/03/22新增)这是懒人的做法, 就是登入login系统后, 出现一个选单, 选单内让你能够选择连上 PTT BBS , 并且自动登入 PTT BBS , 这个有利用expect , 也就是hacker喜欢用的一个工具 , 直接看例子吧 :档案 1 : 命名 bbs.sh#!/bin/bashwhile 1 ; do clear echo = echo (1) PTT BBS #批注:我只给一个选项 for test echo (q) QUIT #批注:要更多 请自己加 echo (0) 离开选单 #批注:要更多 请自己加 echo = echo -n your choice? = read ans case $ans in 1) ptt.expect #批注:所以你还必须有个 ptt.expect 档案 ; q) kill -9 $MY_PID #批注:这个必须在你的 .login 中注明 ; 0) exit ; *) echo Please choose the number from the list ; esacdone档案结束档案 2 : 命名 ptt.expect #系统必须安装expect套件喔#!/usr/local/bin/expect - #批注:路径请自行修改喔set host 2 #批注:这里是ptt.cc的 IP , 用ptt.cc也OKspawn telnet $hostexpect 入代号send supermanr #批注:把你的账号名称放这里expect 输入您的密send supermanisgoodboyr #批注:把你的密码放这里send rinteract档案结束档案 3 : $HOME/.login or $HOME/.bashrc or $HOME/.tcshrc 依照你自己设定 看看你一进入系统会读取哪个档案 我只有用两行 说明 当然你可能还有自己的变量 or 设定export MY_PID $ #批注:这个是给 bbs.sh 用的bbs.sh #启动刚刚的 bbs.sh 路径自己写.档案结束移除字符串与字符串间的空白这个透过简单的 sed 命令即可达成 , 例如我的档案如下:aaaaa :12345bbbb:33333ccc : 5555可以透过这样的命令让档案变成:aaaaa:12345bbbb:33333ccc:5555cat file | sed s/ /g利用awk找出档案内重复的纪录假如我的档案内容如下:account1:passwd1account2:passwd2account3:passwd3account2:passwd4account4:passwd5account6:passwd6account1:passwd7可以看到 account1 与 account2 都有两笔纪录, 可以透过这样的 awk 命令找出这两笔纪录 : (请注意第二个字段的 passwd不同喔)awk -F: x$1+ print $1 is duplicated filename 似乎: uniq -d 也可达到这个目的. 刚刚才发现将档案内的大写字符串转换成小写字符串 (档案内大小写字符串转换)比如说我有一个档案内容如下 : A123456HSULeeg56712345768ABC我可以透过一行命令, 就可以把档案内大写字母, 转换成小写字母: awk print(tolower($0) filename 上面命令会产生 STDOUT : a123456hsuleeg56712345768abc再利用导向方式接起来就可以了 那如果要转换成大写字母呢? 一样的命令, 只是改成:awk print(toupper($0) filename档案内容比对 (找出档案内容差异) 常见的应用比如说, 公司本身有LDAP server, 而email server的账号是从LDAP server同步过来的, 我们就可以利用这个档案内容比对的方式, 找出差异的账号, 也就是需要新增 or 删除的部份:不讨论取得ldap server与email server账号的命令, 不过取出账号的时候, 请特别注意, 强烈建议要先做过排序, 可以透过 sort 命令,直接举例如下:ldap清单(file1):email server清单(file2):两个档案, 很清楚下面档案少了 与 我们可以用命令来达成 :diff -u file1 file2 (请注意 file1 file2 的顺序会影响命令输出)- 3 2009-09-02 09:22:37.000000000 +0800+ 4 2009-09-02 09:22:44.000000000 +0800 -1,6 +1,4 xxxxexample

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论