为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

bash编程教学实例

2011-10-18 32页 pdf 169KB 17阅读

用户头像

is_251197

暂无简介

举报
bash编程教学实例 bash编程教学实例 bash编程 -------------------------------------------------------------------------------- 時間:2004/03/02    來源:不详   Shell Script(bash)简介   众所皆知地,UNIX上以小工具著名,利用许多简单的小工具,来完成原本需要大量软 体开发的工作,这一点特色,使得UNIX成为许多人心目中理想的系统平台。    在众多的小工具中,Shell Script算得上是最基本、最强...
bash编程教学实例
bash编程教学实例 bash编程 -------------------------------------------------------------------------------- 時間:2004/03/02    來源:不详   Shell Script(bash)简介   众所皆知地,UNIX上以小工具著名,利用许多简单的小工具,来完成原本需要大量软 体开发的工作,这一点特色,使得UNIX成为许多人心目中理想的系统平台。    在众多的小工具中,Shell Script算得上是最基本、最强大、运用最广泛的一个。它 运用围之广,不但从系统启动、程式编译、定期作业、上网连线,甚至安装整个Linux系统, 都可以用它来完成。    因为Shell Script是利用您平日在使用的一些指令,将之组合起来,成为一个"程式"。 如果您平日某些序列的指令下得特别频繁,便可以将这些指令组合起来,成为另 一个新的 指令。这样,不但可以简化并加速操作速度,甚至还可以干脆自动定期执行,大大简化系统 管理工作。    *************************   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",我加上一些实际日常的应用例来说明。希望这样能让那些始终不得其门而入 的人们,多多少少能有点概念。    教学例子   "Hello world" Shell Script    照传统程式教学例,这一节介绍Shell Script的"Hello World"如何撰写。    *************************   #!/bin/sh    # Filename : hello    echo "Hello world!"    *************************   大家应该会注意到第一行的"#!/bin/sh"。在UNIX下,所有的可执行Script,不管是那 一种语言,其开头都是"#!",例如 Perl是 "#!/usr/bin/perl",tcl/tk 是"#!/usr/bin/wish",看您要执行的Script程式位置在那里。您也可以用"#! / bin/bash"、"#!/bin/tcsh"等等,来指定使用特定的Shell。    echo是个bash的内建指令。    *************************   接下来,执行hello这个script:    要执行一个Script的方式有很多种。    *************************   第一种 : 将 hello这个档案的权限设定为可执行。    [foxman@foxman bash]# chmod 755 hello    执行    [foxman@foxman bash]# ./hello    hello world    *************************   第二种 : 使用bash内建指令"source"或"."。    [foxman@foxman bash]# source hello    hello world    或    [foxman@foxman bash]# . hello    hello world    *************************   第三种 : 直接使用sh/bash/tcsh指令来执行。    [foxman@foxman bash]# sh hello    hello world    或    [foxman@foxman bash]# bash hello    hello world    *************************   Bash执行选项    *************************   -c string : 读取 string来当命令。    -i : 互动介面。    -s : 由 stdin读取命令。    - : 取消往后选项的读取。    -norc : 不要读~/.bashrc来执行。    -noprofile : 不要读/etc/profile、~/.bash_profile、~/.bash_login、~/.profile 等等来执行。    -rcfile filename : 执行 filename,而非~/.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的搭配运用。    *************************   首先我们先来研究如何对系统进行备份。    要对系统进行备份,不外乎便是利用一些压缩工具。在许多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 ... -f xxxx.tar    gzip -9 xxxx.tar    或    tar -r file/dir ... -f xxxx.tar    gzip -9 < xxxx.tar > xxxx.tar.gz    *************************   在解过Linux下档案备份的基本知识后,我们来写一个将档案备份的Script。    #!/bin/sh    # Filename : backup    DIRS="/etc /var /your_directories_or_files"    BACKUP="/tmp/backup.tgz"    tar -c $DIRS | gzip -9 > $BACKUP    其中 DIRS放的是您要备份的档案及目录,BACKUP是您的备份档。可不要将/tmp放进 DIRS中,那样做,您是在做备份的备份,可能将您的硬碟塞爆。    *************************   接下来测试    [foxman@foxman bash]# chmod 755 backup    [foxman@foxman 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可说是不可缺少的一部份。另外,看 您系统中有那些重要的资料需要备份。通常来说,您没有必要备份 /bin、/sbin、/ usr/bin、/usr/sbin、/usr/X11R6/bin等等这些执行档目录。只要备份您重要的档案即可, 别把整个硬 碟备份,那是蛮呆的动作。    *************************   如果您有许多台机器,可利用其中一台任务较轻的内部网路主机,做为主要备份主机。 将所有机器都自动执行备份,然后利用NFS/Coda/Samba等网路档案系统,将备份的资料放 到该备份机器中,该机器则定时收取备份资料,然后您再由该机器中进行一次备份。    这里是整个系统备份的图示。    在您进行之前,先解一下,系统中那些是要备份的,那些是不需要的。    *************************   新的backup   #!/bin/sh    HOSTNAME=`hostname`    DIRS="/etc /var /your_important_directory"    BACKUP="/tmp/$HOSTNAME.tgz"    NFS="/mnt/nfs"    tar -c $DIRS | gzip -9 > $BACKUP    mv -f $BACKUP $NFS    *************************   备份主机内的Script : collect_backup   #!/bin/sh    NFS="/mnt/nfs"    BACKUP="/backup"    mv -f $NFS/*.tgz $BACKUP    在此,您不能够将所有备份都直接放在/mnt/nfs,这是危险的。万一任一台机器不小心 将/mnt/nfs所有内容删除,那么备份就会消失。因此,您需要将/mnt/nfs移到一个只有该 备份主机可存取的目录中。    *************************   当这些个别的Script都测试好以后,接下来我们将他们放到crontab里面。找到您的 crontab,它的位置可能在/var/spool/cron/crontabs/root、/etc/crontab、/ var/cron/tabs/root。    在crontab中选择以下之一加入(看您定期的时间):    Slackware : /var/spool/cron/crontabs/root   01 * * * * /full_backup_script_path/backup 1> /dev/null 2> /dev/null # 每小 时(太过火一点)    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:30    0 5 1 * * /full_backup_script_path/backup 1> /dev/null 2> /dev/null # 每月 一号5:0    RedHat/Debian : /etc/crontab   RedHat可直接将backup放入/etc/cron.hourly, /etc/cron.daily, / etc/cron.weekly, /etc/cron.monthly。或采用如上加入/etc/crontab的方式:    有关 crontab的用法,可查"man 5 crontab",在此不详述。    备份主机的设定类同。    注意: 所有机器不要同时进行备份,否则网路会大塞车。备份主机收取备份的时间要设 为最后,否则会收不到备份资料。您可以在实作后,将时间间隔调整一下。    *************************   看看,两个小小不到三行的Shell Script,配合cron这个定时工具。可以让原本需要 耗时多个小时的人工备份工作,简化到不到十分钟。善用您的想像力,多加一点变化,可你 让您的生活变得轻松异常,快乐悠哉。   档案系统检查   系统安全一向是大多数电脑用户关心的事,在UNIX系统中,最重视的事,即系统中有 没有"木马"(Trojan horse)。不管 Trojan horse如何放进来的,有一点始终会不变,即被 放置木马的档案,其档案日期一定会被改变,甚至会有其它的状态改变。此外,许多状况下, 系统会多出一些不 知名的档案。因此,平日检查整个档案系统的状态是否有被改变,将所 有状态有改变的档案,以及目前有那些程式正在执行,自动给系统管理员,是个避免坐 上 "木马"的良方。    *************************   #!/bin/sh    # Filename : whatever_you_name_it    DIRS="/etc /home /bin /sbin /usr/bin /usr/sbin /usr/local /var / your_directory"    ADMIN="email@your.domain.com"    FROM="admin@your.domain.com"    # 写入Sendmail的标头    echo "Subject: $HOSTNAME filesystem check" > /tmp/today.mail    echo "From: $FROM" >> /tmp/today.mail    echo "To: $ADMIN" >> /tmp/today.mail    echo "This is filesystem report comes from $HOSTNAME" >> /tmp/today.mail    # 报告目前正在执行的程式    ps axf >> /tmp/today.mail    # 档案系统检查    echo "File System Check" >> /tmp/today.mail    ls -alR $DIRS | gzip -9 > /tmp/today.gz    zdiff /tmp/today.gz /tmp/yesterday.gz >> /tmp/today.mail    mv -f /tmp/today.gz /tmp/yesterday.gz    # 寄出信件    sendmail -t < /tmp/today.mail    然后把它放到一个不显眼的地方去,让别人找不到。    把它加入crontab中。    30 7 * * * /full_check_script_path/whatever_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上面。list是一 序列的工作。如果[in word;]省略掉,那么 name将会被设定为Script后面所加的参数。    *************************   例一:    #!/bin/sh    for i in a b c d e f ; do    echo $i    done    它将会显示出 a到 f。    *************************   例二: 另一种用法,A-Z   #!/bin/sh    WORD="a b c d e f g h i j l m n o p q r s t u v w x y z"    for i in $WORD ; do    echo $i    done    这个Script将会显示 a到 z。    *************************   例三 : 修改副档名   如果您有许多的.txt档想要改名成.doc档,您不需要一个一个来。    #!/bin/sh    FILES=`ls /txt/*.txt`    for txt in $FILES ; do    doc=`echo $txt | sed "s/.txt/.doc/"`    mv $txt $doc    done    这样可以将*.txt档修改成*.doc档。    *************************   例四 : meow   #!/bin/sh    # Filename : meow    for i ; do    cat $i    done    当您输入"meow file1 file2 ..."时,其作用就跟"cat file1 file2 ..."一样。    *************************   例五 : listbin    #!/bin/sh    # Filename : listbin    for i in /bin/* ; do    echo $i    done    当您输入"listbin"时,其作用就跟"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=${i#/etc/rc.d/rc$runlevel.d/S??}    [ -f /var/lock/subsys/$subsys ] || \    [ -f /var/lock/subsys/${subsys}.init ] && continue    # Bring the subsystem up.    $i start    done    这个例中,它找出/etc/rc.d/rcX.d/S*所有档案,检查它是否存在,然后一一执行。    流程控制 case   case word in [ pattern [ | pattern ] ... ) list ;; ] ... esac   case/esac的标准用法大致如下:  case $arg in    pattern | sample) # arg in pattern or sample    ;;    pattern1) # arg in pattern1    ;;    *) #default    ;;  esac    arg是您所引入的参数,如果arg内容符合pattern项目的话,那么便会执行pattern 以下的程式码,而该段程式码则以两个分号";;"做结尾。    可以注意到"case"及"esac"是对称的,如果记不起来的话,把"case"颠倒过来即可。  *************************   例一 : paranoia #!/bin/sh  case $1 in      start | begin)       echo "start something"      ;;      stop | end)       echo "stop something"      ;;      *)       echo "Ignorant"      ;;  esac    执行   [foxman@foxman bash]# chmod 755 paranoia    [foxman@foxman bash]# ./paranoia    Ignorant    [foxman@foxman bash]# ./paranoia start    start something    [foxman@foxman bash]# ./paranoia begin    start something    [foxman@foxman bash]# ./paranoia stop    stop something    [foxman@foxman bash]# ./paranoia end    stop something  *************************   例二 : inetpanel   许多的daemon都会附上一个管理用的Shell Script,像BIND就附上ndc,Apache就附 上apachectl。这些管理程式都是用shell script来写的,以下示一个管理inetd的 shell script。  #!/bin/sh  case $1 in    start | 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等等, 而各平台之间,多多少少都有不同之处,有时候需要判断目前正在那一种平台上执行。此时, 我们可以利用uname来找出系统资讯。  #!/bin/sh  SYSTEM=`uname -s`  case $SYSTEM in    Linux)      echo "My system is Linux"      echo "Do Linux stuff here..."    ;;    FreeBSD)      echo "My system is FreeBSD"      echo "Do FreeBSD stuff here..."    ;;    *)      echo "Unknown system : $SYSTEM"      echo "I don't what to do..."    ;;  esac    流程控制 select   select name [ in word; ] do list ; done   select顾名思义就是在word中选择一项。与for相同,如果[in word;]省略,将会使 用Script后面所加的参数。    例: #!/bin/sh  WORD="a b c"  select i in $WORD ; do   case $i in    a)     echo "I am A"    ;;    b)     echo "I am B"    ;;    c)     echo "I am C"    ;;    *)     break;    ;;   esac  done    执行结果   [foxman@foxman bash]# ./select_demo  1) a  2) b  3) c  #? 1  I am A  1) a  2) b  3) c  #? 2  I am B  1) a  2) b  3) c  #? 3  I am C  1) a  2) b  3) c  #? 4    返回状态Exit   在继续下去之前,我们必须要切入另一个话题,即返回状态值 - 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分别会返回 0/1(成功/失败):    /* yes.c */    void main(void) { exit(0); }    /* no.c */    void main(void) { exit(1); }    那么以下这个"YES"的 shell script便会显示"YES"。    #!/bin/sh    # YES    if yes ; then    echo "YES"    fi    而"NO"不会显示任何东西。    #!/bin/sh    # NO    if no ; then    echo "YES"    fi    *************************   test express    [ express ]    在Shell script中,test express/[ express ]这个语法被大量地使用,它是个非常 实用的指令。由于它的返回值即Exit Status,经常被运用在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 : 当档案存在并且是正常档案时,返回 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。    -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 : 当 file1与 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其中之一为 True。    arg1 OP arg2 : OP是-eq[equal]、-ne[not-equal]、-lt[less-than]、-le[less- than-or-equal]、-gt [greater-than]、-ge[greater-than-or-equal]的其中之一。    *************************   在Bash中,当错误发生在致命信号时,bash会返回 128+signal number做为返回值。 如果找不到命令,将会返回 127。如果命令找到了,但该命令是不可执行的,将返回 126。 除此以外,Bash本身会返回最后一个 指令的返回值。若是执行中发生错误,将会返回一个 非零的值。    Fatal Signal : 128 + signo    Can't not find command : 127    Can't not execute : 126    Shell script successfully executed : return the last command exit status    Fatal during execution : return non-zero   流程控制 if   if list then list [ elif list then list ] ... [ else list ] fi   几种可能的写法  ************************* 第一种  if list then   do something here  fi  当list表述返回值为 True(0)时,将会执行"do something here"。  例一 : 当我们要执行一个命令或程式之前,有时候需要检查该命令是否存在,然后才执行。   if [ -x /sbin/quotaon ] ; then    echo "Turning on Quota for root filesystem"    /sbin/quotaon /  fi  例二 : 当我们将某个档案做为设定档时,可先检查是否存在,然后将该档案设定值载入。 # Filename : /etc/ppp/settings  PHONE=1-800-COLLECT  #!/bin/sh  # Filename : phonebill  if [ -f /etc/ppp/settings ] ; then    source /etc/ppp/settings    echo $PHONE  fi  执行  [foxman@foxman ppp]# ./phonebill  1-800-COLLECT  ************************* 第二种  if list then   do something here  else   do something else here  fi  例三 : Hostname  #!/bin/sh  if [ -f /etc/HOSTNAME ] ; then    HOSTNAME=`cat /etc/HOSTNAME`  else    HOSTNAME=localhost  fi  ************************* 第三种  if list then   do something here  elif list then   do another thing here  fi  例四 : 如果某个设定档允许有好几个位置的话,例如crontab,可利用if then elif fi来 找寻。  #!/bin/sh  if [ -f /etc/crontab ] ; then    CRONTAB="/etc/crontab"  elif [ -f /var/spool/cron/crontabs/root ] ; then    CRONTAB="/var/spool/cron/crontabs/root"  elif [ -f /var/cron/tabs/root ] ; then    CRONTAB="/var/cron/tabs/root"  fi  export CRONTAB  ************************* 第四种  if list then   do something here  elif list then   do another thing here  else   do something else here  fi  例五 : 我们可利用uname来判断目前系统,并分别做各系统状况不同的事。  #!/bin/sh  SYSTEM=`uname -s`  if [ $SYSTEM = "Linux" ] ; then   echo "Linux"  elif [ $SYSTEM = "FreeBSD" ] ; then   echo "FreeBSD"  elif [ $SYSTEM = "Solaris" ] ; then   echo "Solaris"  else   echo "What?"  fi  控制圈 while/until while list do list done 当 list为 True时,该圈会不停地执行。  例一 : 无限回圈写法  #!/bin/sh  while : ; do   echo "do something forever here"   sleep 5  done  例二 : 强迫把 pppd杀掉。  #!/bin/sh  while [ -f /var/run/ppp0.pid ] ; do    killall pppd  done  ************************* until list do list done 当 list为 False(non-zero)时,该圈会不停地执行。  例一 : 等待 pppd上线。  #!/bin/sh  until [ -f /var/run/ppp0.pid ] ; do    sleep 1  done    参数与变数   在继续下去介绍 function之前,我们必须停下来介绍"参数与变数"。    *************************   参数(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...。使用时,用$0,$1,$2...。    位置参数是当script被载入时,后面所附加的参数。$0是本身,$1则为第一个参数, $2为第二个,依此类推。而当 Positional Parameters被function所使用时,它们会被暂 时取代(下一节会介绍 function)。    例如以下这个script:    #!/bin/sh    # Filename : position    echo $0    echo $1    执行时:    [foxman@foxman bash]# ./position abc    ./position    abc    当位置参数超过两位数时,有特别的方法来展开,称为 Expansion。    *************************   特殊参数(Speical Parameters)    这些符号,非常不人性,对新手来说很困扰。但上手后,会觉得方便无比,有些如果您 看不懂的话,就--算了,不用浪费太多时间在上面。    *************************   * 星号    将 Positional Parameters合成一个参数,其间隔为IFS内定参数的第一个字元(见内 建变数一节)。    例:    #!/bin/sh    # starsig    echo $*    执行:    [foxman@foxman bash]# starsig a b c d e f g    a b c d e f g    *************************   @ at符号    与*星号类同。不同之处在于不参照IFS。    例:    #!/bin/sh    # atsig    echo $@    执行:    [foxman@foxman bash]# atsig a b c d e f g    a b c d e f g    *************************   # 井字号    展开 Positional parameters的数量。    例:    #!/bin/sh    # poundsig    echo $#    执行    [foxman@foxman bash]# poundsig a b c d e f g    7    *************************   ? 问号    最近执行的 foreground pipeline的状态。    *************************   - 减号    最近执行的 foreground pipeline的选项参数。    *************************   $ 钱钱钱    本身的 Process ID。    [foxman@foxman bash]# ps ax | grep bash    1635 p1 S  0:00 /bin/bash    [foxman@foxman bash]# echo $$    1635    *************************   ! 惊号    最近执行背景命令的 Process ID。    *************************   0 零    在 Positional Parameters一部份已经说明过了,是执行的shell script本身。但如 果是用"bash -c",则$0被设为第一个参数。    [foxman@foxman bash]# echo $0    /bin/bash    *************************   _ 底线符号    显示出最后一个执行的命令。    [foxman@foxman bash]# echo $_    bash    *************************   内建变数(Shell Variables)    Bash有许多内建变数,像 PATH、HOME、ENV......等等。这些内建变数将在另一节中, 专门一一说明。   函数 function   [ function ] name () { list; }   function的参数是 Positional Paraments。    例  #!/bin/sh  function func() {   echo $1   echo $2   return 1  }  func "Hello" "function"    局部变数可用local来宣告。    函数可export,使用下一层的shell可以使用。    函数可递,没有递层数的限制。   Bash内建指令集    以下的命令,大部份都没有使用例,您可能会看不出所以然,摸不著头脑。在我加入例 说明前,建议您"man bash",然后自己实际操作一次。    *************************   : [arguments]    不做任何事,除了[arguments]一些参数展开及一些特定重导向的作业外。    永远返回零。它的用法跟 true一样。    *************************   . filename [arguments]    source filename [arguments]    由filename中读取命令,并执行。    您会在/etc/rc.d/*中发现很多    . /xxxx    的指令,而xxxx的 permission都不是可执行的。事实上,在tcsh中,需要用    source /xxxx    来做同样的指令。    注意到"."的后面是有空格的(比较一下". /"跟"./",不一样)。filename是内含指令 的纯文字档即可,无须 chmod 755 filename。    例   filename : my_source    DEV=lo    IP=127.0.0.1    NETMASK=255.0.0.0    BROADCAST=127.255.255.255    ifconfig $IP netmask $NETMASK broadcast $BROADCAST dev $DEV    接下来    . my_source    或    source my_source    便可执行该script,而不需要"chmod 755 my_source"    *************************   alias [name[=value] ...]    昵称命令    例如您如果来自 DOS的世界,对UNIX的指令不习惯,可用alias来修改,以符合您的 习惯。    例   alias ls="ls --color"    alias dir="ls"    alias cd..="cd .."    alias copy="cp -f" # dangerous, recommend, "cp -i"    alias del="rm -f" # dangerous, recommend, "rm -i"    alias move="mv -f" # dangerous, recommend, "mv -i"    alias md="mkdir"    alias rd="rmdir"    *************************   unalias [-a] [name ...]    unalias取消 alias的设定。"unalias -a"将全部 alias取消。    例   unalias copy    *************************   bg [jobspec]    将指定任务放到背景中,如果 jobspec未指定,内定为目前的。    *************************   fg [jobspec]    将指定任务放到前景中,如果 jobsepc没有指定,那么内定为目前的。    *************************   jobs [-lnp] [ jobspec ... ]    第一种形式列出目前正在工作的任务。    -l : 除了列出一般资讯外,还列出Process IDs。    -p : 仅列出该工作群"首脑"(Process group leader)的 Process ID.    -n : 则仅列出有改变的 jobs的状态。    如果给定 jobspec,输出资讯则只有该 jobspec。    返回值为零,除非有非法的选项发生。    jobs -x command [ args ... ]    如果使用第二种形式(-x),jobs取代指定的command及 args,并执行返回其 Exit Status。    *************************   kill [-s sigspec | -sigspec] [pid | jobspec] ... 
/
本文档为【bash编程教学实例】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索