Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。
Shell 是指一种应用程序,这个应用程序提供了一个界面,用户经过这个界面访问操做系统内核的服务。
Ken Thompson 的 sh 是第一种 Unix Shell,Windows Explorer 是一个典型的图形界面 Shell。
当一个用户登录linux 系统后,系统就会为该用户建立一个shell程序。
Shell的版本:linux
echo命令能够显示文本行或变量取值,或者把字符串输入到文件中
格式: echo string
echo的经常使用功能:\c 不换行 \f 不进纸 \t 跳格 \n 换行shell
note:
对于linux系统,必须使用-e选项来使以上转义符生效编程
例:bash
$ echo -e "hello\tboy" hello boy
echo命令对特殊字符敏感,若是要输出特殊字符,须要用\屏蔽其特殊含义。
经常使用的特殊字符:双引号"" 反引号`` 反斜线\
例:app
$ echo "\"\"" //想输出"" ""
read命令从键盘或者文件的某一行文本中读入信息,并将其赋给一个变量。
若是只指定了一个变量,read会把全部的输入赋给该变量,直至遇到第一个文件结束符或回车
格式: read var1 var2 …
例1:函数
chenshifengdeMacBook-Pro:~ chenshifeng$ read name Hello I am superman chenshifengdeMacBook-Pro:~ chenshifeng$ echo $name Hello I am superman
若是输入的值个数多于变量个数,多余的值会赋给最后一个变量:
例2:oop
chenshifengdeMacBook-Pro:~ chenshifeng$ read name surname John Mike Kate chenshifengdeMacBook-Pro:~ chenshifeng$ echo $surname Mike Kate chenshifengdeMacBook-Pro:~ chenshifeng$
cat能够用来显示文件,而且支持将多个文件串链接后输出测试
note:该命令一次显示完整个文件,若想分页查看,需使用moreui
格式: cat [ options ] filename1 … filename2 …
经常使用options:spa
例:
$ cat file1 file2 file3 // 同时显示三个文件 $ cat –b file1 file2 file3
能够经过管道把一个命令的输出传递给另一个命令作为输入
格式: 命令1 | 命令2
例:
$ cat test.txt | grep 'hello'
把输出的一个副本输送到标准输出,另外一个副本拷贝到相应的文件中
若是想看到输出的同时,把输出也同时拷入一个文件,这个命令很合适
格式: tee -a file
tee命令通常和管道符|结合起来使用
例:
$ who | tee who.info // 该命令的信息返回在屏幕上,同时保存在文件who.info中
$ who | tee who.info chenshifeng console Jan 9 12:56 chenshifeng ttys000 Jan 9 13:27 chenshifeng ttys004 Jan 9 19:11 chenshifeng ttys005 Jan 10 00:12 $ cat who.info chenshifeng console Jan 9 12:56 chenshifeng ttys000 Jan 9 13:27 chenshifeng ttys004 Jan 9 19:11 chenshifeng ttys005 Jan 10 00:12
当咱们在shell中执行命令的时候,每一个进程都和三个打开的文件相联系,并使用文件描述符来引用这些文件,见下表
文件 | 文件描述符 |
---|---|
输入文件-标准输入 | 0 |
输出文件-标准输出 | 1 |
错误输出文件-标准错误 | 2 |
系统中实际上有12个描述符,能够任意使用文件描述符3-9
标准输入 对应文件描述符0,是命令的输入,缺省键盘
标准输出 对应文件描述符1,是命令的输出,缺省屏幕或文件
标准错误 对应文件描述符2,是命令错误的输出,缺省屏幕或文件
利用文件重定向功能对命令的标准输入,输出和错误进行修改。
经常使用文件重定向命令:
command > file: 标准输出重定向到一个文件,错误仍然输出屏幕 command >> file: 标准输出重定向到一个文件(追加) command 1> file: 标准输出重定向到一个文件 command 2> >file: 标准错误重定向到一个文件(追加) command >file 2>&1: 标准输出和标准错误一块儿重定向到一个文件 command >>file 2>&1: 标准输出和标准错误一块儿重定向到一个文件(追加) command < file1 >file2: 以file1作为标准输入,file2作为标准输出 command <file: 以file作为文件标准输入
结合使用标准输出和标准错误
$ cat hello 1>myfile.out 2>myerror.out
合并标准输出和标准错误
$ cat >>mylog.out 2>&1 <hello
cron是系统的调度进程,可在无人干预的状况下运行做业,经过crontab的命令容许用户提交,编辑或者删除相应的做业。
每一个用户均可以有一个crontab文件来保存调度信息,经过该命令运行任意一个shell脚本或者命令
在大的系统中,系统管理员能够经过cron.deny和cron.allow这两个文件来禁止或容许用户拥有本身的crontab文件
crontab的域
第1列 分钟0~59
第2列 小时0~23(0表示子夜)
第3列 日1~31
第4列 月1~12
第5列 星期0~6(0表示星期天)
第6列 要运行的命令
crontab格式: 分<>时<>日<>月<>星期<>要运行的命令
<>表示空格
note:若是要表示范围的话,如周一到周五,能够用1-5表示
若是要列举某些值,如周1、周五,能够用1,5表示
例1:
30 21 * * * /apps/bin/cleanup.sh
例2:
0,30 18-23 * * * /apps/bin/dbcheck.sh
crontab的命令选项
格式:crontab [ -u user ] -e -l -r
其中
1 建立一个文件,建议名为
0,10,20,30,40,50 * * * * /bin/echo "hello boy"
保存退出
2 提交刚刚建立的cron文件shifengcron
$ crontab shifengcron $ ls /var/spool/cron/ 是否生成文件shifengcron
$ crontab –l $ crontab –l > $HOME/mycron 能够经过这种方法对crontab进行备份
$ crontab -e
修改后保存退出,cron会对其进行必要的完整性检查
$ crontab –r
若是误删了crontab文件,假设在$HOME目录下还有备份,能够将这个备份文件拷贝到/var/spool/cron/
$ crontab <filename>
note:filename是备份的crontab文件的名字
at命令容许用户向cron守护进程提交做业,使其在稍后的时间运行,这个时间能够是10min之后,也多是几天之后,但若是时间比较长,建议仍是使用crontab
格式:at [ -f script ] [ -m -l -r ] [ time ] [ date ]
能够经过命令行方式或者at命令提示符方式来提交做业,通常来说,若是提交多个命令,可使用at命令提示符;若是提交的是shell脚本,可使用命令行方式
例:提示符方式:
$ at 01:15 at > echo “hello” at > echo “boy” >/home/wuxh/at.log at > <EOT>
note:EOT是Ctrl+D,任务执行后,会给当前用户发送邮件,经过mail命令能够查看相关信息,也能够将信息重定向到文件
例:提交shell脚本方式
$ at 3:00pm tomorrow –f /home/wuxh/hello.sh
note:该脚本将在明天下午3点运行,使用脚本方式,要加参数-f
列出at任务,格式:at -l
例:
$ at -l 5 2021-01-17 11:20 a root
note: 第一个是做业标识id;第二个是日期;第三个是时间;a表明at;第四个表明建立任务的用户
清除at任务
格式:at -r
$ at –r [ job no]
例:$ at -r 5
note:不接job no将清除全部未执行的任务,接具体job id将清楚对应的任务
当在前台运行某个做业时,终端被该做业占据;而当它在后台运行时,它不会占据终端
能够借助&命令把做业放到后台执行
格式: 命令 &
注:
1 .须要用户交互的命令不要放在后台执行,不然机器一直等待
2 .后台程序在执行时,执行结果仍然会输出到屏幕,干扰咱们的工做,建议将这样的信息重定向到某个文件
即:command > out.file 2>&1 &
将标准输入错误输出都定向到一个out.file的文件中
例:$ find /etc/ -name "hello" -print >find.dt 2>&1 &
"" | 双引号 |
---|---|
` | 反引号 |
'' | 单引号 |
\ | 反斜线 |
可引用除字符$,`,\
外的任意字符或者字符串,对$,`,\
敏感
例1:
$ echo "hello" hello
例2:
$ echo "$$" 8311 ///想输出字符$$ 结果看到的是数值8311 $ echo "\$$" //对特殊字符须要反斜线屏蔽其特殊含义 $$ //获得想要的结果
例3:
$ echo "`V_V`" //想输出`V_V`字样 结果获得错误信息 $ echo "\`V_V\`" //获得`V_V`输出
单引号和双引号的用法基本相似,不一样的是单引号对特殊字符不敏感,能够将其作为普通字符输出出来
例:
$ echo '$$' //结果 $$ 不用借助\进行屏蔽 $ echo '`V_V`' //结果`V_V`,和前页双引号比较
该命令用于设置系统命令的输出到变量,shell将反引号中的内容作为命令执行。
例1:
$ echo `hello` -bash: hello: command not found
例2:
$ echo `date` 2021年 1月17日 星期日 23时40分18秒 CST
反引号能够和双引号结合起来使用:
例3:
$ echo "The date today is `date`" The date today is 2021年 1月17日 星期日 23时41分15秒 CST
若是一个字符有特殊含义,为防止shell误解其含义,可用\屏蔽该字符
具备特殊含义的字符
------------------------------------------------------------------------------------
& * ^ $ ` “ |
------------------------------------------------------------------------------------
例1 :
$ echo "$$" //在屏幕上输出$$字符,结果显示3853 $ echo "\$$" //用反斜线屏蔽,防止shell误解,结果显示$$
例2:
$ echo * //在屏幕上输出*字符,结果输出当前目录下内容 $ echo \* //用反斜线屏蔽,防止shell误解,输出*字符
系统变量适用于全部用户进程,能够在命令行中设置,但用户注销时这些值将丢失,最好在.profile中进行定义,或者/etc/profile
传统上,全部环境变量都大写,且必须用export命令导出
设置环境变量:
var_name=value; export var_name
或者:
var_name=value export var_name
又或者
export var_name=value
查看环境变量:
echo $var_name
嵌入shell变量
通常来说,bourne shell有一些预留的环境变量名,这些变量名不能作其余用途,一般在/etc/profile中创建这些嵌入的环境变量,但这不绝对,取决于用户
shell的变量列表:
CDPATH; EXINIT; HOME; IFS; LOGNAME; MAIL;MAILCHECK; PATH; PS1; PS2; SHELL; TERMINFO;TERM; TZ
在用户shell生命周期的脚本中使用,不一样的用户能够定义各自的用户变量 ~/.bashrc
用法:
var_name=value
显示变量:
echo $var_name or echo ${var_name} //建议使用
清除变量:
unset var_name
显示用户全部变量:set
测试变量是否设置:echo ${var:=value} 若未设置或未初始化,可用新值
使用变量保存系统命令参数
例:
$ SOURCE="/etc/passwd" $ DEST="/home/chenshifeng/ $ cp $SOURCE $DEST
设置只读变量
可设置某个变量为只读方式,只读变量不可更改,不然系统返回错误
用法:
var_name=value readonly var_name
例:
$ myvar="100" $ readonly myvar $ myvar="200" $ -bash: myvar: readonly variable
位置变量属于只读变量
做用:向shell脚本传递参数,参数个数能够任意多,但只有前9个被访问到,shift命令能够更改这个限制。
每一个访问参数前加$,
第一个参数为0,表示预留保存实际脚本名字,不管脚本是否有参数,此值都可用,如:给脚本test传递信息:
Would you like to do it
$0 | $1 | $2 | $3 | $4 | $5 | $6 | $7 | $8 | $9 |
---|---|---|---|---|---|---|---|---|---|
脚本名字 | would | you | like | to | do | it |
例:$ vi test
#!/bin/sh echo "The full name is : $0 " echo "The script name is : `basename $0`" echo "The first parameter is :$1" echo "The second parameter is :$2" echo "The third parameter is :$3" echo "The fourth parameter is :$4" echo "The fifth parameter is :$5" echo "The sixth parameter is :$6" echo "The seventh parameter is :$7" echo "The eighth parameter is :$8" echo "The ninth parameter is :$9"
保存文件,执行 $ ./test would you like to do it
The full name is : ./test The script name is : test The first parameter is :would The second parameter is :you The third parameter is :like The fourth parameter is :to The fifth parameter is :do The sixth parameter is :it The seventh parameter is : The eighth parameter is : The ninth parameter is :
note:上例中
$0
返回的信息中包含路径名,若是只想获得脚本名称,能够借助basename,将脚本中第一句修改成:
echo "The script name is : \`basename \$0\` "
保存文件,执行 ./test would you like to do it
note:basename 用``向系统命令传递参数
能够在脚本中向系统命令传递参数
$ vi findfile #!/bin/sh find / -name $1
保存,执行
$ ./findfile passwd
特定变量属于只读变量,反映脚本运行过程当中的控制信息
特定的shell变量列表:
变量 | 说明 |
---|---|
$# | 传递到脚本的参数个数(经常使用) |
$* | 以一个单字符串的形式显示全部向脚本传递的参数,与位置变量 不一样,此项参数可超过9个 |
$$ | 脚本运行的当前进程id号(经常使用) |
$! | 后台运行的最后一个进程的进程id号 |
$@ | 与$*相同,可是使用时加引号,并在引号中返回每一个参数 |
$- | 显示shell使用的当前变量,与set命令功能相同 |
$? | 显示最后命令的退出状态,0表示正确,其余任何值表示错误(经常使用) |
例:修改test脚本,追加特定变量信息:
#!/bin/sh echo "The full name is : $0 " echo "The script name is : `basename $0`" echo "The first parameter is :$1" echo "The second parameter is :$2" echo "The third parameter is :$3" echo "The fourth parameter is :$4" echo "The fifth parameter is :$5" echo "The sixth parameter is :$6" echo "The seventh parameter is :$7" echo "The eighth parameter is :$8" echo "The ninth parameter is :$9" echo "The number of arguments passed :$#" echo "Show all arguments :$*" echo "Show my process id :$$" echo "Show me the arguments in quotes :$@" echo "Did my script go with any errors :$?"
最后的退出状态 $?
能够在任何脚本或者命令中返回此变量以得到返回信息,基于此信息,能够在脚本中作更进一步的研究,返回0为成功,1为失败
例1:
$ cp /etc/passwd /home/chenshifeng/myfile $ echo $? 0
例2:
$ cp /etc/passwd /home/wuxh/mydir //<mydir不存在> $ echo $? 1
建议将返回值设置为一个有意义的名字,增长脚本的可读性
修改例2
$ cp_status=$? $ echo $cp_status
测试文件状态:
用法:test condition 或者 [ condition ]
文件状态列表
例:
$ ls -l hello $ [ -w hello ] $ echo $?
使用逻辑操做符:
测试文件状态是否ok,能够借助逻辑操做符对多个文件状态进行比较
例1:
$ [ -r myfile1 -a -w myfile2 ] $ echo $?
例2:
$ [ -w myfile1 -o -x myfile2 ] $ echo $?
字符串测试是错误捕获很重要的一部分,特别是用户输入或比较变量时尤其重要
格式:
注:string_operator 的取值:
= 等于 != 不等于 -z 空串 -n 非空串
例:测试变量string1是否等于string2
$ string1="hello" $ string2="Hello" $ [ "$string1" = "$string2" ] $ echo $?
note:在进行字符串比较时,必定要加引号;等号先后要加空格。
格式:"number" number_operator "number"
或者:[ "number" number_operator "number" ]
number_operator 的取值范围:
比较符 | 说明 |
---|---|
-eq | 数值相等 |
-gt | 第一个数大于第二个数 |
-ne | 数值不相等 |
-lt | 第一个数小于第二个数 |
-le | 第一个数小于等于第二个数 |
-ge | 第一个数大于等于第二个数 |
例1:
[root@chenshifengdeLinuxServer ~]# NUM1=130 [root@chenshifengdeLinuxServer ~]# [ "$NUM1" -eq "130" ] [root@chenshifengdeLinuxServer ~]# echo $? 0
例2:
[root@chenshifengdeLinuxServer ~]# [ "990" -le "996" -a "123" -gt "33" ] [root@chenshifengdeLinuxServer ~]# echo $? 0
通常用于整数值,也能够用于字符串;
格式:expr argument operator argument
expr 也是个手工命令行的计数器
$ expr 10 + 10 #注意空格 $ expr 300 / 6 / 5 $ expr 30 \* 3 #注意:乘号必须用反斜线屏蔽其特定含义
expr在循环中用于增量计算,首选,循环初始化为0,而后循环加1,经常使用的作法:从expr接受输出赋给循环变量
例:
$ LOOP=0 $ LOOP=`expr $LOOP + 1`
能够用expr测试一个数,若是对非整数进行计算,则返回错误
例:
$ expr 1.1 + 1 #返回错误 $ expr 1 + 1 #返回2
注 expr 也有返回的状态,但与系统最后返回的值恰好相反,expr返回成功为1,其余值为失败。
例:
$ value=hello $ expr $value = "hello" 1 # 这是expr执行成功的值 $ echo $? 0 # 这是系统返回的成功的值
格式:
if 条件1 then 命令1 elif 条件2 then 命令2 else 命令3 fi
注意:使用if语句时,必须将then部分放在新行,不然会产生错误,若是要不分行,必须使用命令分割符,即:
if 条件1; then 命令1 fi
例:$ vi myfile
#!/bin/sh DIRECTORY=$1 if [ "`ls -A $DIRECTORY`" = "" ] ; then echo "$DIRECTORY is indeed empty" else echo "$DIRECTORY is not empty" fi
格式:
for 变量名 in 列表 do 命令1 命令2 done
说明:命令 可为任何有效的shell命令和语句
变量名能够为任何单词
in列表是可选的,若是没有列表,for循环会使用命令行的位置参数
in列表能够包含替换,字符串,文件名
例:
#!/bin/sh for loop1 in 1 2 4 5 6 #数字列表 do echo $loop1 done for loop2 in he is a tall man #字符串列表 do echo $loop2 done for loop3 in `ls` #替换列表 do echo $loop3 done
对for 循环使用参数,当循环中省去in列表选项时,它将接受命令行特定变量作为参数即
for params in "$@" 或者 for params in "$*"
例1:
#!/bin/sh for params in "$@" do echo "You supplied $params as a command line option" done echo $params
例2
#!/bin/sh counter=0 for files in `ls` do counter = `expr $counter + 1` done echo "There are $counter files in `pwd`"
while循环
格式:
while 命令 do 命令1 命令2 …… done
note:do和done之间命令,只有前一个返回状态为0,后面命令才会被执行;不然则循环停止
until循环
格式:
until 条件 命令1 命令2 …… done
note:until执行一系列命令,只至条件为真时中止,循环至少执行一次。
例1:
#!/bin/sh echo "Type <Ctrl-D> to terminate" echo -n "enter your favorate film :" while read FILM do echo "Yeah,great film the $FILM" done
使用ctrl-D中断脚本的执行,整个循环停止
例2:
#!/bin/sh IS_ROOT=`who | grep root` until [ "$IS_ROOT" ] do sleep 5 IS_ROOT=`who | grep root` done echo "Watch it. Roots in " | mail wuxh
思考:为何用sleep 5?
格式:
case 值 in 模式1) 命令1 …… ;; 模式2) 命令2 …… ;; esac
case 取值后面必须为in,每一个模式必须以右括号结束,取值能够为变量或者常数,找到匹配模式后,执行相关命令直到;;
模式部分能够包含元字符,与命令行中文件扩展名中使用的匹配类型相符,如 * ? [..]
例:
#!/bin/sh if [ $# != 1 ]; then echo "Usage:`basename $0` [start|stop|help]" exit 1 fi OPT=$1 case $OPT in start) echo "starting..`basename $0`" # code here to start a process ;; stop) echo "stopping..`basename $0`" # code here to stop a process ;; help) # code here to display a help page ;; *) echo "Usage:`basename $0` [start|stop|help]" ;; esac
有时须要某些准则退出循环或者跳过循环步,就须要break和continue来实现
break 容许跳出循环或者case语句,在嵌套循环里,能够制定跳出的循环个数,例在两层的嵌套循环内,break 2能够跳出整个循环
continue 相似于break,区别是continue只会跳过当前的循环步,而不会跳出整个循环
例子1:
#!/bin/sh while : do echo -n "Enter any number [1..5] :" read ANS case $ANS in 1|2|3|4|5) echo "great you entered a number between 1 and 5" ;; *) echo "wrong number..bye" break ;; esac done
例子2 :
names2.txt 内容包含雇员名字,部门,及其id,以下所示:
------------------------------内容以下--------------------------------
---LISTING OF PERSONNEL FILE----
--- TAKEN AS AT 06/1999----------------
Louise Conrad:Accounts:ACC8987
Peter James:Payroll:PR489
Fred Terms:Customer:CUS012
James Lenod:Accounts:ACC887
Frank Pavely:Payroll:PR489
-------------------------------------------------------------------------------
要求:读取names2.txt文件,将在职员工的名字,部门,部门id读取打印出来
说明:Peter James已经离职
使用IFS读文件
输出时要去除冒号域分隔符,可以使用变量IFS。在改变它以前保存IFS的当前设置。而后在脚本执行完后恢复此设置。
使用IFS能够将域分隔符改成冒号而不是空格或t a b键,这里有3个域须要加域分隔,即NAME、DEPT和ID。脚本以下:
#!/bin/sh # save the setting of IFS SAVEDIFS=$IFS # assign new separator to IFS IFS=: INPUT_FILE=names2.txt NAME_HOLD="Peter James" LINE_NO=0 if [ -s $INPUT_FILE ]; then while read NAME DEPT ID do LINE_NO=`expr $LINE_NO + 1` if [ "$LINE_NO" -le "2" ]; then continue fi if [ "$NAME" = "$NAME_HOLD" ]; then continue else echo "Now processing …$NAME $DEPT $ID" fi done < $INPUT_FILE # restore the settings of IFS IFS=$SAVEDIFS else echo "`basename $0 ` : Sorry file not found or there is no data in the file >&2" exit 1 fi
Shell 容许将一组命令集或语句造成一个可用块,这些块称为shell函数,其组成部分:
函数标题,函数体
标题是函数名,应该惟一;函数体是命令集合
函数格式:
函数名() { 命令1 … } 或者 function 函数名() { …. }
函数能够只放在同一个文件中作为一段代码,也能够放在只包含函数的单独文件中
注:函数必须在使用前定义,通常放于脚本开始部分,直至shell解释器首次发现它时,才可使用
例脚本func1:
#!/bin/sh hello() { echo "Hello,today’s date is `date`" } echo "now, going to the function hello" hello echo "back from the function"
向函数传递参数就象在通常脚本中使用特殊变量$1,$2..\(9同样,函数取得所传参数后,将原始参数传回shell,能够在函数内定义本地变量保存所传的参数,通常这样的参数名称以_开头 例:脚本对输入的名字进行检查,只能包含字母 \) vi func2
#!/bin/sh echo -n "what is your first name :" read F_NAME char_name() { _LETTERS_ONLY=$1 _LETTERS_ONLY=`echo $1|awk '{if($0~/[^a-z A-Z]/) print "1"}'` if [ "$_LETTERS_ONLY" != "" ] then return 1 else return 0 fi } if char_name $F_NAME; then echo "ok" else echo "ERRORS" fi
函数执行完毕或者基于某个测试语句返回时,可做两种处理:
return 从函数中返回,用最后状态命令决定返回值 return 0 无错误返回 return 1 有错误返回
能够直接在脚本调用函数语句的后面使用最后状态命令来测试函数
调用的返回值
例:
hello #这里是hello函数被调用 if [ $? = 0 ] then echo “it is ok” else echo “something is wrong with hello function” fi
更好的办法是使用if语句测试返回0仍是返回1,能够在if语句里面将函数调用用括号括起来,增长可读性,如 if hello ; then
若是函数将从测试结果中反馈输出,可使用替换命令保存结果,函数调用的替换格式为
variable_name=function_name
函数function_name输出被设置到变量variable_name中
经常使用的一些函数能够收集起来,放入函数文件,使用时,将文件载入shell中
文件头应该以#!/bin/sh开头,文件名可任意选取,但建议有说明性。
文件一旦载入shell,就能够在命令行或者脚本中调用函数,可使用set产看全部定义的函数,输出列表包括已经载入shell的全部函数。
要想改动文件,首先用unset命令从shell中删除函数,注,这里不是真正的删除,修改完毕后,再将文件从新载入,有些shell会识别改动,没必要使用unset,但建议改动时使用unset命令
例:function.main
#!/bin/sh findit() { if [ $# -lt 1 ]; then echo "Usage :findit file" # 思考:为何用findit,不用$0? return 1 fi find / -name $1 -print }
格式:<点><空格><路径><文件名>
$. ./function.main
使用set命令查看已经载入shell中的函数
$ set
要执行函数,简单的键入函数名,若是须要参数,后跟参数便可
$ findit hello
若是须要对函数作改动,须要借助unset命令先从shell中删除函数,修改后,再从新载入
$ unset findit 修改… $ . ./function.main
set -n 读命令但不执行 set -v 显示读取的全部行 set -x 显示全部命令及其参数 set +x set选项关闭
例:vi error_file
#!/bin/sh set –x LIST="Peter Susan John Barry Lucy Norman Bill Leslie" echo -n "Enter your name :" read NAME for LOOP in $LIST do if [ "$LOOP" = "$NAME" ];then echo "you’re on the list, you’re in" break fi done set +x
运行脚本
$ ./error_file
执行结果:
error + error + LIST=Peter Susan John Barry Lucy Norman Bill Leslie + echo –n Enter your Name: Harry + [ Peter = Harry ] + [ Susan = Harry ] + [ John = Harry ] + [ Barry = Harry ] + [ Lucy = Harry ] + [ Norman = Harry ] + [ Bill = Harry ] + [ Leslie = Harry ]