bash编程入门_第1页
bash编程入门_第2页
bash编程入门_第3页
bash编程入门_第4页
bash编程入门_第5页
已阅读5页,还剩27页未读 继续免费阅读

下载本文档

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

文档简介

1、.bash编程入门shell script(bash)简介众所皆知地,unix上以小工具著名,利用许多简单的小工具,来完成原本需要大量软体开发的工作,这一点特色,使得unix成为许多人心目中理想的系统平台。在众多的小工具中,shell script算得上是最基本、最强大、运用最广泛的一个。它运用围之广,不但从系统启动、程式编译、定期作业、上网连线,甚至安装整个linux系统,都可以用它来完成。因为shell script是利用您平日在使用的一些指令,将之组合起来,成为一个程式。如果您平日某些序列的指令下得特别频繁,便可以将这些指令组合起来,成为另一个新的指令。这样,不但可以简化并加速操作速度,

2、甚至还可以干脆自动定期执行,大大简化系统管理工作。*bash(gnu bourne-again shell)是许多linux平台的内定shell,事实上,还有许多传统unix上用的shell,像tcsh、csh、ash、bsh、ksh等等,shell script大致都类同,当您学会一种shell以后,其它的shell会很快就上手,大多数的时候,一个shell script通常可以在很多种shell上使用。这里我介绍您bash的使用方法。事实上,当您man bash时,就可以看到bash的说明书,不过对许多人来说,这份说明书犹如无字天书一样难懂。这份文件,主要资料来源为man bash,我加上

3、一些实际日常的应用例来说明。希望这样能让那些始终不得其门而入的人们,多多少少能有点概念。教学例子hello world shell script照传统程式教学例,这一节介绍shell script的hello world如何撰写。*#!/bin/sh# filename : helloecho hello world!*大家应该会注意到第一行的#!/bin/sh。在unix下,所有的可执行script,不管是那一种语言,其开头都是#!,例如perl 是#!/usr/bin/perl,tcl/tk是#!/usr/bin/wish,看您要执行的script程式位置在那里。您也可以用#! /bin/

4、bash、#!/bin/tcsh等等,来指定使用特定的shell。echo是个bash的内建指令。*接下来,执行hello这个script:要执行一个script的方式有很多种。*第一种 : 将hello这个档案的权限设定为可执行。foxmanfoxman bash# chmod 755 hello执行foxmanfoxman bash# ./hellohello world精品.*第二种 : 使用bash内建指令source或.。foxmanfoxman bash# source hellohello world或foxmanfoxman bash# . hellohello world*第

5、三种 : 直接使用sh/bash/tcsh指令来执行。foxmanfoxman bash# sh hellohello world或foxmanfoxman bash# bash hellohello world*bash执行选项*-c string : 读取string来当命令。-i : 互动介面。-s : 由stdin读取命令。- : 取消往后选项的读取。-norc : 不要读/.bashrc来执行。-noprofile : 不要读/etc/profile、/.bash_profile、/.bash_login、/.profile等等来执行。-rcfile filename : 执行fil

6、ename,而非/.bashrc-version : 显示版本。-quiet : 启动时不要哩唆。-login : 确保bash是个login shell。-nobraceexpansion : 不要用curly brace expansion(符号展开)。-nolineediting : 不用readline来读取命令列。-posix : 改采posix 1003.2标准。用于自动备份的shell script一个用于自动备份的shell script我们先前提到,可利用shell script搭配crond来作定期的工作。要作定期性的工作,在unix上,就是与crond的搭配运用。*首先我

7、们先来研究如何对系统进行备份。要对系统进行备份,不外乎便是利用一些压缩工具。在许多unix系统上,tar及gzip是de facto的资料交换标准。我们经常可以看见一些tar.gz或tgz档,这些档案,被称为tarball。当然了,您也可以用bzip2、zip等等压缩工具来进行压缩,不必限定于gzip。但tar配合gzip是最普遍的,也是最方便的方式。要将我们想要的资料压缩起来,进行备份,可以结合tar及gzip一起进行。方式有很多种,最常用的指令是以下这一种:精品.tar -c file/dir . | gzip -9 xxxx.tar.gz您也可以分开来做:tar -r file/dir

8、. -f xxxx.targzip -9 xxxx.tar或tar -r file/dir . -f xxxx.targzip -9 xxxx.tar.gz*在解过linux下档案备份的基本知识后,我们来写一个将档案备份的script。#!/bin/sh# filename : backupdirs=/etc /var /your_directories_or_filesbackup=/tmp/backup.tgztar -c $dirs | gzip -9 $backup其中dirs放的是您要备份的档案及目录,backup是您的备份档。可不要将/tmp放进dirs中,那样做,您是在做备份的备

9、份,可能将您的硬碟塞爆。*接下来测试foxmanfoxman bash# chmod 755 backupfoxmanfoxman bash# ./backup执行完成后在/tmp就会有一个backup.tgz,里面储存了您重要的资料。您可用gzip -dc /tmp/backup.tgz | tar -vt或tar vtfz /tmp/backup.tgz来看看里面的档案列表。要解开时,可用以下指令来完成复原:gzip -dc /tmp/backup.tgz | tar -xv或tar xvfz /tmp/backup.tgz备份通常是仅备份系统通常最重要的部份,/etc可说是不可缺少的一部

10、份。另外,看您系统中有那些重要的资料需要备份。通常来说,您没有必要备份 /bin、/sbin、/usr/bin、/usr/sbin、/usr/x11r6/bin等等这些执行档目录。只要备份您重要的档案即可,别把整个硬碟备份,那是蛮呆的动作。*如果您有许多台机器,可利用其中一台任务较轻的内部网路主机,做为主要备份主机。将所有机器都自动执行备份,然后利用nfs/coda/samba等网路档案系统,将备份的资料放到该备份机器中,该机器则定时收取备份资料,然后您再由该机器中进行一次备份。这里是整个系统备份方案的图示。在您进行之前,先解一下,系统中那些是要备份的,那些是不需要的。*新的backup精品.

11、#!/bin/shhostname=hostnamedirs=/etc /var /your_important_directorybackup=/tmp/$hostname.tgznfs=/mnt/nfstar -c $dirs | gzip -9 $backupmv -f $backup $nfs*备份主机内的script : collect_backup#!/bin/shnfs=/mnt/nfsbackup=/backupmv -f $nfs/*.tgz $backup在此,您不能够将所有备份都直接放在/mnt/nfs,这是危险的。万一任一台机器不小心将/mnt/nfs所有内容删除,那么

12、备份就会消失。因此,您需要将/mnt/nfs移到一个只有该备份主机可存取的目录中。*当这些个别的script都测试好以后,接下来我们将他们放到crontab里面。找到您的crontab,它的位置可能在/var/spool/cron/crontabs/root、/etc/crontab、/var/cron/tabs/root。在crontab中选择以下之一加入(看您定期的时间):slackware : /var/spool/cron/crontabs/root01 * * * */full_backup_script_path/backup 1 /dev/null 2 /dev/null # 每

13、小时(太过火一点)30 16 * * */full_backup_script_path/backup 1 /dev/null 2 /dev/null # 每日16:30,下班前备份30 16 * * 0/full_backup_script_path/backup 1 /dev/null 2 /dev/null # 每周一16:300 5 1 * */full_backup_script_path/backup 1 /dev/null 2 /dev/null # 每月一号5:0redhat/debian : /etc/crontabredhat可直接将backup放入/etc/cron.ho

14、urly, /etc/cron.daily, /etc/cron.weekly, /etc/cron.monthly。或采用如上加入/etc/crontab的方式:有关crontab的用法,可查man 5 crontab,在此不详述。备份主机的设定类同。注意: 所有机器不要同时进行备份,否则网路会大塞车。备份主机收取备份的时间要设为最后,否则会收不到备份资料。您可以在实作后,将时间间隔调整一下。*看看,两个小小不到三行的shell script,配合cron这个定时工具。可以让原本需要耗时多个小时的人工备份工作,简化到不到十分钟。善用您的想像力,多加一点变化,可你让您的生活变得轻松异常,快乐悠

15、哉。精品.档案系统检查系统安全一向是大多数电脑用户关心的事,在unix系统中,最重视的事,即系统中有没有木马(trojan horse)。不管trojan horse如何放进来的,有一点始终会不变,即被放置木马的档案,其档案日期一定会被改变,甚至会有其它的状态改变。此外,许多状况下,系统会多出一些不知名的档案。因此,平日检查整个档案系统的状态是否有被改变,将所有状态有改变的档案,以及目前有那些程式正在执行,自动报告给系统管理员,是个避免坐上木马的良方。*#!/bin/sh# filename : whatever_you_name_itdirs=/etc /home /bin /sbin /u

16、sr/bin /usr/sbin /usr/local /var /your_directoryadmin=from=# 写入sendmail的标头echo subject: $hostname filesystem check /tmp/today.mailecho from: $from /tmp/today.mailecho to: $admin /tmp/today.mailecho this is filesystem report comes from $hostname /tmp/today.mail

17、# 报告目前正在执行的程式ps axf /tmp/today.mail# 档案系统检查echo file system check /tmp/today.maills -alr $dirs | gzip -9 /tmp/today.gzzdiff /tmp/today.gz /tmp/yesterday.gz /tmp/today.mailmv -f /tmp/today.gz /tmp/yesterday.gz# 寄出信件sendmail -t然后把它放到一个不显眼的地方去,让别人找不到。把它加入crontab中。30 7 * * */full_check_script_path/whate

18、ver_you_name_it 1 /dev/null 2 /dev/null #上班前检查有些档案是固定会更动的,像/var/log/messages、/var/log/syslog、/dev/ttyx等等,不要太大惊小怪。控制圈for演示了几个简单的shell script,相信您应该对shell script有点概念了。现在我们开始来仔细研究一些较高等的shell script写作。一些进一步的说明,例如$、1、2符号的使用,会在稍后解释。*for name in word; do list ; done控制圈。word是一序列的字,for会将word中的个别字展开,然后设定到name上

19、面。list是一序列的工作。如果in word;省略掉,那么name将会被设定为script后面所加的参数。精品.*例一:#!/bin/shfor i in a b c d e f ; doecho $idone它将会显示出a到f。*例二: 另一种用法,a-z#!/bin/shword=a b c d e f g h i j l m n o p q r s t u v w x y zfor i in $word ; doecho $idone这个script将会显示a到z。*例三 : 修改副档名如果您有许多的.txt档想要改名成.doc档,您不需要一个一个来。#!/bin/shfiles=ls

20、 /txt/*.txtfor txt in $files ; dodoc=echo $txt | sed s/.txt/.doc/mv $txt $docdone这样可以将*.txt档修改成*.doc档。*例四 : meow#!/bin/sh# filename : meowfor i ; docat $idone当您输入meow file1 file2 .时,其作用就跟cat file1 file2 .一样。*例五 : listbin#!/bin/sh# filename : listbinfor i in /bin/* ; doecho $i精品.done当您输入listbin时,其作用就

21、跟ls /bin/*一样。*例六 : /etc/rc.d/rc拿一个实际的例来说,red hat的/etc/rc.d/rc的启动程式中的一个片断。for i in /etc/rc.d/rc$runlevel.d/s*; do# check if the script is there. ! -f $i & continue# check if the subsystem is already up.subsys=$ -f /var/lock/subsys/$subsys | -f /var/lock/subsys/$.init & continue# bring the subsystem u

22、p.$i startdone这个例中,它找出/etc/rc.d/rcx.d/s*所有档案,检查它是否存在,然后一一执行。流程控制casecase word in pattern | pattern . ) list ; . esaccase/esac的标准用法大致如下:case $arg inpattern | sample) # arg in pattern or sample;pattern1) # arg in pattern1;*) #default;esacarg是您所引入的参数,如果arg内容符合pattern项目的话,那么便会执行pattern以下的程式码,而该段程式码则以两个-

23、more-(28%) 分号;做结尾。可以注意到case及esac是对称的,如果记不起来的话,把case颠倒过来即可。*例一 : paranoia#!/bin/shcase instart | begin)echo start something;stop | end)echo stop something精品.;*)echo ignorant;esac执行foxmanfoxman bash# chmod 755 paranoiafoxmanfoxman bash# ./paranoiaignorantfoxmanfoxman bash# ./paranoia startstart someth

24、ingfoxmanfoxman bash# ./paranoia beginstart somethingfoxmanfoxman bash# ./paranoia stopstop somethingfoxmanfoxman bash# ./paranoia endstop something*例二 : inetpanel许多的daemon都会附上一个管理用的shell script,像bind就附上ndc,apache就附上apachectl。这些管理程式都是用sh ell script来写的,以下示一个管理inetd的shell script。#!/bin/shcase instart

25、| begin | commence) /usr/sbin/inetd;stop | end | destroy) killall inetd;restart | again) killall -hup inetd;*) echo usage: inetpanel start | begin | commence | stop | end | destory | restart | again;esac*例三 : 判断系统有时候,您所写的script可能会跨越好几种平台,如linux、freebsd、solaris等等,而各平台之间,多多少少都有不同之处,有时候需要判断目前正在那一种平台上执行

26、。此时,我们可以利用uname来找出系统资讯。精品.#!/bin/shsystem=uname -scase $system inlinux)echo my system is linuxecho do linux stuff here.;freebsd)echo my system is freebsdecho do freebsd stuff here.;*)echo unknown system : $systemecho i dont what to do.;esac流程控制selectselect name in word; do list ; doneselect顾名思义就是在wo

27、rd中选择一项。与for相同,如果in word;省略,将会使用script后面所加的参数。例:#!/bin/shword=a b cselect i in $word ; docase $i ina)echo i am a;b)echo i am b;c)echo i am c;*)break;esacdone执行结果foxmanfoxman bash# ./select_demo1) a2) b精品.3) c#? 1i am a1) a2) b3) c#? 2i am b1) a2) b3) c#? 3i am c1) a2) b3) c#? 4返回状态exit在继续下去之前,我们必须要切

28、入另一个话题,即返回状态值 - exit status。因为if/while/until都迁涉到了使用exit status来控制程式流程的问题。*许多人都知道,在许多语言中(c/c+/perl.),都有一个exit的函数,甚至连bash自己都有个exit的内建命令。而exit后面所带的数字,便是返回状态值 - exit status。返回状态值可以使得程式与程式之间,利用shell script来结合的可能性大增,利用小程式,透过shell script,来完成很杂的工作。在shell中,返回值为零表示成功(true),非零值为失败(false)。*举例来说,以下这个两个小程式yes/no分

29、别会返回0/1(成功/失败):/* yes.c */void main(void) exit(0); /* no.c */void main(void) exit(1); 那么以下这个yes的shell script便会显示yes。#!/bin/sh# yesif yes ; thenecho yesfi而no不会显示任何东西。#!/bin/sh# no精品.if no ; thenecho yesfi*test express express 在shell script中,test express/ express 这个语法被大量地使用,它是个非常实用的指令。由于它的返回值即exit sta

30、tus,经常被运用在if/while/until的场合中。而在后面,我们也会大量运用到,在进入介绍if/while/until之前,有必要先解一下。其返回值为0(true)或1(false),要看表述(express)的结果为何。express格式-b file : 当档案存在并且属性是block special(通常是/dev/xxx)时,返回true。-c file : 当档案存在并且属性是character special(通常是/dev/xxx)时,返回true。-d file : 当档案存在并且属性是目录时,返回true。-e file : 当档案存在时,返回true。-f file

31、 :当档案存在并且是正常档案时,返回true。-g file :当档案存在并且是set-group-id时,返回true。-k file :当档案存在并且有sticky bit被设定时,返回true。-l file :当档案存在并且是symbolic link时,返回true。-p file :当档案存在并且是name pipe时,返回true。-r file :当档案存在并且可读取时,返回true。-s file :当档案存在并且档案大小大于零时,返回true。-s file : 当档案存在并且是socket时,返回true。-t fd : 当fd被开启为terminal时,返回true。-

32、u file : 当档案存在并且set-user-id bit被设定时,返回true。-w file : 当档案存在并且可写入时,返回true。-x file : 当档案存在并且可执行时,返回true。-o file : 当档案存在并且是被执行的user id所拥有时,返回true。-g file : 当档案存在并且是被执行的group id所拥有时,返回true。file1 -nt file2 : 当file1比file2新时(根据修改时间),返回true。file1 -ot file2 : 当file1比file2旧时(根据修改时间),返回true。file1 -ef file2 : 当f

33、ile1与file2有相同的device及inode number时,返回true。-z string : 当string的长度为零时,返回true。-n string : 当string的长度不为零时,返回true。string1 = string2 : string1与string2相等时,返回true。string1 != string2 : string1与string2不相等时,返回true。! express : express为false时,返回true。expr1 -a expr2 : expr1及expr2为true。expr1 -o expr2 : expr1或expr2其

34、中之一为true。arg1 op arg2 : op是-eqequal、-nenot-equal、-ltless-than、-leless-than-or-equal、 -gtgreater-than 、-gegreater-than-or-equal的其中之一。精品. *在bash中,当错误发生在致命信号时,bash会返回128+signal number做为返回值。如果找不到命令,将会返回127。如果命令找到了,但该命令是不可执行的,将返回126。除此以外,bash本身会返回最后一个指令的返回值。若是执行中发生错误,将会返回一个非零的值。fatal signal : 128 + signo

35、cant not find command : 127cant not execute : 126shell script successfully executed : return the last command exit statusfatal during execution : return non-zero流程控制ifif list then list elif list then list . else list fi几种可能的写法*第一种if list thendo something herefi当list表述返回值为true(0)时,将会执行do something he

36、re。例一 : 当我们要执行一个命令或程式之前,有时候需要检查该命令是否存在,然后才执行。if -x /sbin/quotaon ; thenecho turning on quota for root filesystem/sbin/quotaon /fi例二 : 当我们将某个档案做为设定档时,可先检查是否存在,然后将该档案设定值载入。# filename : /etc/ppp/settingsphone=1-800-collect#!/bin/sh# filename : phonebillif -f /etc/ppp/settings ; thensource /etc/ppp/sett

37、ingsecho $phonefi执行foxmanfoxman ppp# ./phonebill1-800-collect*第二种if list then精品.do something hereelsedo something else herefi例三 : hostname#!/bin/shif -f /etc/hostname ; thenhostname=cat /etc/hostnameelsehostname=localhostfi*第三种if list thendo something hereelif list thendo another thing herefi例四 : 如果

38、某个设定档允许有好几个位置的话,例如crontab,可利用if then elif fi来找寻。#!/bin/shif -f /etc/crontab ; thencrontab=/etc/crontabelif -f /var/spool/cron/crontabs/root ; thencrontab=/var/spool/cron/crontabs/rootelif -f /var/cron/tabs/root ; thencrontab=/var/cron/tabs/rootfiexport crontab*第四种if list thendo something hereelif li

39、st thendo another thing hereelsedo something else herefi例五 : 我们可利用uname来判断目前系统,并分别做各系统状况不同的事。#!/bin/shsystem=uname -sif $system = linux ; then精品.echo linuxelif $system = freebsd ; thenecho freebsdelif $system = solaris ; thenecho solariselseecho what?fi控制圈while/untilwhile list do list done当list为true

40、时,该圈会不停地执行。例一 : 无限回圈写法#!/bin/shwhile : ; doecho do something forever heresleep 5done例二 : 强迫把pppd杀掉。#!/bin/shwhile -f /var/run/ppp0.pid ; dokillall pppddone*until list do list done当list为false(non-zero)时,该圈会不停地执行。例一 : 等待pppd上线。#!/bin/shuntil -f /var/run/ppp0.pid ; dosleep 1done参数与变数在继续下去介绍function之前,我

41、们必须停下来介绍参数与变数。*参数(parameters)是用来储存值的资料型态,有点像是一般语言中的变数。它可以是个名称(name)、数字(number)、或者是以下所列出来一些特殊符号(special parameters)。在shell中,变数是由name形式的参数所构成的。*在前面的许多例中,我们事实上已经看到许多参数的运用。要设定一个parameter实际很简单:name=value精品.例如说:myhost=foxman而要使用它时,则是加个$符号。echo $myhost*位置参数(positional parameters)*所谓的位置参数便是0,1,2,3,4,5,6,7,8,9.。使用时,用,.。位置参数是当script被载入时,后面所附加的参数。是本身,则为第一个参数,为第二个,依此类推。而当positional parameters被function所使用时,它们会被暂时取代(下一节会介绍function)。例如以下这个script:#!/bin/sh# filename : positionecho echo 执行时:foxmanfoxman bash# ./position abc./positionabc当位置参数超过两位数时,有特别的方法来展开,称为expansion。*特殊参数(speical parameters)这些

温馨提示

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

评论

0/150

提交评论