第14章,Shell脚本编程进阶

更多内容请点击:

Linux学习从入门到打死也不放弃,完全笔记整理(持续更新,求收藏,求点赞~~~~)

http://blog.51cto.com/13683480/2095439

本章内容:

条件判断

循环

信号捕捉

函数

数组

高级字符串操作

高级变量

Expect

过程式编程语言执行方式:

顺序执行,选择执行,循环执行

条件选择-----------------------------------------------------------------------

if语句:

结构:     可嵌套

单分支:

if 判断条件;then

条件判断为真的执行代码

fi

双分支:

if 判断条件;then

条件判断为真的执行代码

(此段若想为空,使用":")

else

条件判断为假的执行代码

fi

多分支:

if 条件判断1;then

cmd..

elif  条件判断2;then

cmd..

elif  条件判断3;then

cmd..

else

以上条件全为假的分支代码

fi

case语句:

格式:

case  变量引用 in

pat1)

分支1

;;

pat2)

分支2

;;

...

*)

默认分支

;;

esac

注意:     case支持glob风格的通配符

*             任意长度任意字符

?           任意单个字符

[abc]       指定范围内的任意单个字符

a|b          a或b

循环执行------------------------------------------------------------------------

将某代码段重复多次运行

重复运行多少次

循环次数事先已知

循环次数事先未知

有进入条件和退出条件

for,while,until

for循环

格式:

for 变量名 in 列表;do

循环体代码

done

机制:

依次将列表中的元素赋值给"变量名"

每次赋值后即执行一次循环体,直到列表中的元素耗尽,循环结束

列表生成方式:

1     直接给出列表

2     整数列表

{1..10..2}

$(seq  1 2 10)

3     返回列表的命令

$(cmd)

4     使用glob,如:*.sh

5     变量引用

[email protected],$*

while循环

格式:

while CONDITION;do

循环体

done

CONDITION :

循环控制条件

进入循环之前,先做一次判断

每一次循环之后会再次做判断

条件为true,则执行一次循环,直到条件测试状态为false 终止循环

因此:     CONDITION一般应该有循环控制变量,而此变量的值会在循环体不断的被修正

进入条件:CONDITION为true

退出条件:CONDITION为false

until循环

格式:

until CONDITION;do

循环体

done

进入条件:CONDITION 为  false

退出条件:CONDITION 为  true

循环控制语句:

用于循环体中

continue [N] 默认为1

用于循环体中,提前结束第N层的本轮循环,而直接进入下一轮判断

所在层为第1层

break [N] 默认为1

用于循环体中,提前结束第N层循环,所在层为第1层

shift [N] 默认为1

用于将参数列表list 左移指定的次数,默认1次

参数列表list 一旦被移动,最左端的那个参数就从列表中删除。

while循环遍历位置参数列表时,常用到shift

创建无限循环:

1     while true;do

循环体代码

done

2     until false;do

循环体

done

特殊用法:

while 循环的特殊用法(遍历文件的每一行)

while read  变量名;do

循环体代码

done <  /file

一次读取file 文件中的每一行,且将行赋值给变量

PS:   也可以使用   cmd |while read;do

循环体

done

但是循环中的数组值貌似不能输出,即如在done之后echo 数组中的值为空 ,需要注意

双小括号方法,即((....))格式,也可以用于算术运算

也可以是bash实现C语言风格的变量操作

i=10

((i++))

for 循环 的特殊格式:

for((控制变量初始化;条件判断表达式;控制标量的修正表达式));do

循环体代码

done

如:       for ((i=1;i<=10;i++));do

echo  $i

done

控制变量初始化:

仅在运行到循环代码段时执行一次

控制变量的修正表达式:

条件判断表达式:进入循环先做一次条件判断,true则进入循环

每轮循环结束会先进行控制变量的修正运算,而后在做条件判断

select循环与菜单:

格式:

select  变量  in  列表;do

循环体命令

done

select  循环主要用于创建菜单,按数字顺序排列的菜单项将显示在标准错误上,并显示

PS3提示符,等待用户输入

用户输入菜单列表上的某个数字,执行相应的命令

用户输入被保存在内置变量REPLY中

PS2:     多行重定向的提示符

PS3:     select的提示符

REPLY     保存select的用户输入

select与case

select是个无限训话,因此要记住用break命令退出循环,或用exit命令终止脚本。

也可以按Ctrl+c退出循环

select  经常和case联合使用

与for循环类似,可以省略in list ,此时使用位置参量

trap 信号捕捉:

trap ‘触发指令’信号

自定义进程收到系统发出的指定信号后,将执行触发指令,而不会执行原操作

trap ''信号

忽略信号的操作

trap '-' 信号

恢复原信号的操作

trap -p

列出自定义信号操作

注意事项:

信号:    格式可以是 int INT sigint SIGINT 2

信号捕捉之后,虽然不会立刻结束脚本,但是脚本当前运行的命令却会被终止

如:       trap 'echo trap a sig2'  2

sleep  10000

ping  192.168.0.1

如果捕捉到2信号,不会退出脚本,但是sleep会被打断,而继续执行ping命令

函数:------------------------------------------------------------------------------

函数介绍:

函数function是由若干条shell命令组成的语句块,实现代码重用和模块化编程

它与shell程序形式上是相似的,不同的是它不是一个单独的进程,不能独立运行,

而是shell程序的一部分

函数和shell程序区别在于:

shell程序在子shell中运行

而shell函数在当前shell中运行。因此在当前shell中,函数可以对shell变量

进行修改

定义函数:

函数由两部分组成:函数名和函数体

help  function

语法1:

f_name(){

函数体

}

语法2:

function f_name()

{

函数体

}

语法3:

function f_name{

函数体

}

可以交互式环境下定义函数,如:

[[email protected] ~/bin]$func_name1(){

>  echo nihao

>  echo wohenhao

>  ping  -c1 -w1  192.168.0.1

>  }

[[email protected] ~/bin]$func_name1

nihao

wohenhao

connect: Network is unreachable

可将函数放在脚本文件中作为它的一部分

可放在只包含函数的单独文件中

函数调用:

函数只有被调用才会执行

函数名出现的地方,会被自动替换为函数代码

函数的生命周期:

被调用时创建,返回时终止

在脚本中用户前必须定义,因此应该将函数定义放在脚本开始部分,直至shell首次

发现它之后才能使用

调用函数仅使用其函数名即可

函数返回值:

函数由两种返回值:

函数的执行结果返回值:

1     使用echo等命令进行输出

2     函数体中调用命令的输出结果

函数的退出状态码:

1      默认取决于函数中执行的最后一条命令的退出状态码

2     自定义退出状态码,return命令

return  :        从函数中返回,用最后状态命令决定返回值

return 0 无错误返回

return 1-255 有错误返回

删除函数:

unset  func_name1

函数文件:

创建函数文件:

#!/bin/bash

# function.main

f_hello()

{

echo  helio

}

f_func2(){

...

}

...

系统自带函数文件:/etc/rc.d/init.d/functions

使用函数文件:

可以将进程使用的函数存入函数文件,然后将函数文件载入shell

文件名可任意选取,但最好与相关任务有某种联系,如  function.main

一般函数文件载入shell,就可以在命令行或脚本中调用函数,

可以使用set命令查看所有定义的函数,其输出列表包括已经载入shell的所有函数

若要改动函数,首先用unset命令从shell中删除函数,改动完毕后,再重新载入此文件

载入函数:

要想使用已创建好的函数文件,要将他载入shell

使用

.  /path/filename

source  /path/filename

如果使用source 载入函数之后,对函数文件的某个函数做了修改,需要unset函数之后重新载入

unset  func_name1

或者exit 重新登录然后再次source

默认本shell进程有效,如需函数子进程有效,需声明

export -f func_name

declare  -xf

如需查看当前所有的全局函数

export -f  或 declare -xf

例如:

[[email protected]  ~/bin]$export -f func_release

[[email protected]  ~/bin]$export -f

func_release ()

{

declare  rel=$(cat /etc/centos-release|tr -dc [0-9]|cut  -c1);

echo  $rel

}

declare -fx  func_release

[[email protected]  ~/bin]$

函数参数:

函数可以接受参数:

调用函数时,在函数名后面以空白分隔给定参数列表即可;

例如 func_name arg1 arg2 ...

在函数体当中,可以使用$1,$2..调用这些参数;还可以使用[email protected],$*,$# 等特殊变量

注意区分脚本的位置参数和传递给函数的位置参数

函数变量:

变量作用域:

环境变量:    当前shell和子shell有效

本地变量:    只在当前shell进程有效,为执行脚本会启动专用shell进程;

因此,本地变量的作用范围是当前shell脚本程序文件,包括脚本中的函数

局部变量:     函数的生命周期;函数结束时变量会被自动销毁

注意:     如函数中的变量名同本地变量,使用局部变量

函数中定义局部变量:

local  name=

declare name=            declare自带局部变量属性

declare -ig  在函数中定义普通变量,centos6不支持

函数递归:

函数直接或间接调用自身

注意递归层数

函数递归示例:

阶乘是基斯顿·卡曼于 1808 年发明的运算符号,是数学术语

一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且有0的

阶乘为1,自然数n的阶乘写作n!

n!=1×2×3×...×n

阶乘亦可以递归方式定义:0!=1,n!=(n-1)!×n

n!=n(n-1)(n-2)...1

n(n-1)! =  n(n-1)(n-2)!

示例:

fact.sh

#!/bin/bash

func_factorial()

{

if [ $1 = 0 ];then

echo  1

else

echo  $[$1*`func_factorial $[$1-1]`]

fi

}

func_factorial  $1

fork×××:

fork×××是一种恶意程序,它的内部是一个不断fork进程的无限循环,实质是一个简单

的递归程序。由于程序是递归的,如果没有任何显示,这会导致整个简单的程序迅速

耗尽系统所有资源

函数实现:

:(){  :|:&};:

bomb(){ bomb|bomb&};bomb

脚本实现:

cat  bomb.sh

#!/bin/bash

./$0|./$0&

多种语言版本

数组---------------------------------------------------------------------------------

变量:     存储单个元素的内存空间

数组:     存储多个元素的连续的内存空间,相当于多个变量的集合

数组名和索引:

索引:编号从0开始,属于数值索引

bash4.0版本之后,索引可以支持使用自定义的格式,而不仅是数值格式,即为关联索引

bash中的数组支持稀疏格式(索引不连续)

声明数组:

declare -a array_name

declare -A  ARRAY_NAME 关联索引

彼此不可互相转化

数组赋值:

数组元素的赋值:

1     一次只赋值一个元素

array_name[index]=VALUE

如:

weekdays[0]="sunday"

weekdays[4]="thursday"

2     一次赋值全部元素

array_name=("VAL1" "val2" "val3"...)

3     只赋值特定元素

array_name=([0]=varl [3]=val2...)

4     交互式数组值对赋值

read -a array_name1

如:

[[email protected] ~]$read -a  array_name1

monday  tusday wensday thursday

[[email protected] ~]$echo  ${array_name1[@]}

monday  tusday wensday thursday

注意:

如果先赋值单个元素array[0]=a,

再使用赋值全部 array=(b c d) 或者特定赋值 array=([1]=e [2]=f  [3]=g)

会使之前单个元素array[0]被覆盖消失

索引数组可以无需声明直接赋值使用

关联数组必须先声明之后才能赋值使用

如:[[email protected] ~]$array3[0]=mage

[[email protected] ~]$array3[1]=zhangsir

[[email protected] ~]$echo  ${array3[*]}

mage  zhangsir

[[email protected] ~]$echo  ${array3[1]}

zhangsir

[[email protected] ~]$echo  ${array3[0]}

mage

[[email protected] ~]$array4[ceo]=mage

[[email protected] ~]$array4[cto]=zhangsir

[[email protected] ~]$echo  ${array4[*]}

zhangsir

直接赋值使用关联数组会赋值失败,只显示最后一个值

数组引用:

引用数组元素:

${array_name[index]}

注意:省略[index表示引用下标为0的元素]

引用数组所有元素

${array_name[@]}

${array_name[*]}

数组的长度(数组中元素的个数)

${#array_name[*]}

${#array_name[@]}

删除数组中的某元素:导致稀疏格式

unset  array[index]

删除整个数组

unset  array

数组数据处理

引用数组中的元素:

数组切片:${array[@]:offset:number}

offset:     要跳过的元素个数

number:要取出的元素个数

${array[0]:offset}            取偏移量之后的所有元素

${array[0]: -n}              取最后n个元素

${array[0]::2}                 取开头2个元素

${array[0]:  -m:-n}         跳过最后第n+1个到第m个元素间的所有元素

向数组中追加元素:

array[${#array[*]}]=

关联数组:

declare -A  array_name

array_name=([idx_name1]=val1 [idx_name2]=val2  ...)

字符串处理-------------------------------------------------------------------------

字符串切片:

${#var}:                         返回字符串变量var的长度

${var:offset}:                  返回字符串变量var中从第off个字符后(不包括第offset个字符)的字符

开始,到最后的部分,offer的取值在0到${#var}-1之间(bash4.2之后允许为负值)

${var:offset:number}:     返回字符串变量var中第off个之后的num个字符(不包含off)

${var: -n}:                            取字符串最右侧那个字符(冒号后需加一个空格)

${var: -n:-m}:                取倒数第m+1个字符 到 倒数第n个字符

基于模式取子串:

${var#*word}        其中var为变量名,不需要加$引用,word可以是指定的任意字符串

功能:自左而右,查找var变量所存储的字符串中,第一次出现的word,删除字符串开头

至第一次出现word字符之间的所有字符

${var##*word}

贪婪模式,删除字符串开头到最后一次”word“指定的字符之间的所有内容

${var%word*}         其中word可以是指定的任意字符串

功能:    自右边而左,查找var变量所存储的字符串中,第一次出现word,删除字符串最后一个字符

向左至第一次出现word字符之间的所有字符

${var%%word*}

自右而左,删除至最后一个word所指定的字符串

查找替换:

${var/pattern/substr}:

查找var所表示的字符串中,第一次被pattern所匹配到的字符串,以substr替换之

${var//pattern/substr}:

替换所有能被pattern所匹配到的字符串,以substr替换

${var/#pattern/substr}

行首被pattern匹配,并替换

${var/%pattern/substr}:

行尾被pattern匹配,并替换

查找删除:

${var/pattern}:               删除第一次被pattern匹配到的字符串

${var//pattern}:       删除所有被pattern匹配到的字符串

${var/#pattern}:     删除pattern为行首所匹配到的字符串

${var/%pattern}:     删除pattern为行尾所匹配到的字符串

字符串大小写转换:

${var^^} 把var中所有的小写字母转换为大写

${var,,}    把var中所有的大写字母转换为小写

高级变量用法:-------------------------------------------------------------------

变量赋值:

var=${str-expr}      str为变量,expr为字符串

如果str没有没配置,var=expr

如果str配置且为空,var=

如果str配置且非空,var=$str

var=${str:-expr}

如果str没有配置或者为空,var=expr

如果str已配置且非空:      var=$str

其他诸多用法,此处不一一列举,如有需要查看相关表格查询

高级变量用法:有类型变量

shell变量一般是无类型的,但是bash  shell提供了declare和同样typeset两个命令

用于指定变量的类型,两个命令是等价的

declare:

declare [option] [var]

-r           声明或显示只读变量

-i           整型数

-a          数组

-A          关联数组

-f           显示已定义的所有函数名及其内容

-F           仅显示已定义的所有函数名

-x          声明或显示环境变量和函数

-xf 全局函数

-l           声明变量为小写字母

-u          声明变量为大写字母

declare -ig   在函数中定义普通变量,centos6不支持

eval:

eval命令将会首先扫描命令进行所有的置换,然后再执行该命令。该命令适用于那些一次

扫描无法实现其功能的变量:该命令对变量进行两次扫描

示例:    eval  echo {1..$i}

间接变量引用:

如果第一个变量的值是第二个变量的名字,从第一个变量引用第二个变量的值

就称为间接变量引用

如:

var1=var2

var2=nnn

bash 提供了两种格式实现间接变量引用

eval  var=\$$var1

var3=${!var1}

如:

var1=var2

var2=nnn

var3=${!var1} 或者 eval var3=\$$var1

echo  $var3

nnn

创建临时文件:---------------------------------------------------------------------

mktemp :

创建并显示临时文件,可避免冲突

mktemp [option]..[template]

template:       filenameXXX

-d          创建临时目录

-p DIR 或 --tmpdir=DIR     指明临时文件所存放目录位置

示例:

tmpfile1=`mktemp  httptmp-XXX`

tmpdir=`mktemp -d  /tmp/roottmp-XXXX`

tmpdir=`mktemp  --tmpdir=/tmp roottmp-XXXX`

安装复制文件:

install       命令:

install [options] source  dest       单文件

install [] source dir                    单文件

install [] -t dir source           单文件

install [] -d  dir            创建空目录

选项:

-m mode 默认755

-o  owner

-g  group

示例:

expect介绍-----------------------------------------------------------------------

expect 是由Don Libes 基于Tcl(Tool Command Language)语言开发的

主要应用于自动化交互式操作的场景,借助expect处理交互的命令,可以将交互过程

如:ssh登录,ftp登录等写在一个脚本上,使之自动化完成。尤其适用于需要对多台

服务器执行相同操作的环境中,可以大大提供系统管理人员的工作效率

expect命令:

expect [选项] [-c cmds] [[ -f[f|b]] cmdfile ]  [args]

选项:

-c          从命令行执行expect脚本,默认expect是交互地执行的

示例:expect -c 'expect "hello" { send "you said  hello\n" }'

-d          可以输出调试信息

示例:expect -d ssh.exp

expect中的相关命令

spawn           启动新的进程

send              用户向进程发送字符串

expect            从进程接受字符串

interact   允许用户交互

exp_continue 匹配多个字符串,在执行动作后加此命令

expect最常用的语法(tcl语言:模式-动作)

单一分支模式语法:

expect "hi"  { send "you said hi \n"}

匹配到hi后,会输出"you said  hi",并换行

多分支模式语法:

expect "hi"  { send "You said hi\n" } \

"hehe" { send "Hehe yourself\n" } \

"bye" { send "Good bye\n" }

?  匹配hi,hello,bye任意字符串时,执行相应输出。等同如下:

expect  {

"hi"  { send "You said hi\n"}

"hehe"  { send "Hehe yourself\n"}

"bye"  { send "Good bye\n"}

}

expect 示例:

ssh自动键入密码

#!/usr/bin/expect

spawn ssh  192.168.65.132

expect  {

"yes/no"  { send "yes\n";exp_contunue }

"password"  { send "112233\n"; }

}

interact

#expect  eof

scp自动键入密码

#!/usr/bin/expect

spawn scp /etc/passwd  192.168.65.132:/data

expect  {

"yes/no"  { send "yes\n";exp_continue }

"password"  {send "112233\n" }

}

expect eof

自动从文件获取ip地址,且登录ip地址机器的root账号,并创建账号

也可以不用条用,直接在bash脚本中引用expect代码

cat ssh.exp

#!/usr/bin/expect

set ip [lindex $argv  0]

set user [lindex  $argv 1]

set password [lindex  $argv 2]

spawn ssh  [email protected]$ip

expect  {

"yes/no" { send "yes\n";exp_continue  }

"password" { send "$password\n"  }

}

expect "]#" { send "useradd user1\n" }

expect "]#" { send "echo nagedu |passwd --stdin  user1\n"}

send  "exit\n"

#interact

expect eof

cat   sshauto.sh

#!/bin/bash

while read ip;do

user=root

password=112233

ssh.exp $ip $user  $password

done <  /root/bin/ip.txt

自动从文件获取ip地址,并scp同一文件到所有主机的root目录.txt

#!/bin/bash

declare  password=112233

while read ip;do

expect  <<EOF

spawn scp  /root/bin/scpauto.sh $ip:/root

expect  {

"password" { send "112233\n"  }

}

expect  eof

EOF

done <  /root/bin/ip.txt

笔记整理完成时间:2018年5月16日20:21:12

原文地址:http://blog.51cto.com/13683480/2120909

时间: 2024-10-15 13:58:04

第14章,Shell脚本编程进阶的相关文章

shell脚本编程进阶练习题

这两天学习了shell脚本编程进阶,作为一枚文科生,小编觉得...恩..脚本很烧脑.....,不过小编还是做了些题,稍作总结后,呈给各位看官,内容如下: 一.条件选择if语句 选择执行: 注意:if语句可嵌套 单分支 if 判断条件;then 条件为真的分支代码 fi 双分支 if 判断条件; then 条件为真的分支代码 else 条件为假的分支代码 fi 多分支 if 判断条件1; then 条件为真的分支代码 elif 判断条件2; then 条件为真的分支代码 elif 判断条件3; t

SHELL脚本编程进阶(二)

写在前面(最重要) 本文部分资料和示例援引自以下书籍.在此,感谢原作者的创作,以及所有译者的付出,向他们致敬. Advanced Bash-Scripting Guide <高级Bash脚本编程指南>Revision 10中文版 Linux脚本编程执导 其中 <高级Bash脚本编程指南>Revision 10中文版 是 <Advanced Bash-Scripting Guide> 的中文翻译版,文档翻译正在进行中,再次感谢译者付出. 前言 在之前的文章 Linux 基

SHELL脚本编程进阶(一)

写在前面(最重要) 本文部分资料和示例援引自以下书籍.在此,感谢原作者的创作,以及所有译者的付出,向他们致敬. Advanced Bash-Scripting Guide <高级Bash脚本编程指南>Revision 10中文版 Linux脚本编程执导 其中 <高级Bash脚本编程指南>Revision 10中文版 是 <Advanced Bash-Scripting Guide> 的中文翻译版,文档翻译正在进行中,再次感谢译者付出. 前言 在之前的文章中,我们已经详细

shell脚本编程进阶

前言:进入正题之前我们先来复习一下有关脚本编程的条件测试 一,流程控制 过程式编程语言 a.顺序执行 b.选择执行 c.循环执行 顺序执行 顾名思义,就是按照你脚本里所敲的内容顺序执行 选择执行 fi a.条件选择if语句,可以嵌套 b.格式 单支 if 判断条件;then 条件为真 fi 双分支 if 判断条件;then 条件为真 else 条件为假 fi 多分支 if 判断条件;then 条件为真 elif(相当于else if) 判断条件;then 条件为真 else 上述条件都为假 fi

shell脚本编程——进阶篇(真刀实干)

条件测试 文件测试 整数测试 字符串与逻辑测试 if语句 if单分支语句 if双分支语句 if多分支语句 if嵌套语句 test命令测试特定的表达式 是否成立,当条件成立时,测试语句的返回值为0,否则为其他数值. 格式1:test 条件表达式 格式2:[ 条件表达式 ] (注意前后至少有1个空格,否则不予执行) 文件测试格式:[ 操作符 文件或目录 ]常用的测试操作符:1.-d:测试是否为目录(Directory)2.-e:测试目录或文件是否存在(Exist)3.-f:测试是否为文件(File)

《Linux命令行与Shell脚本编程大全第2版.布卢姆》pdf

下载地址:网盘下载 内容简介  · · · · · · 本书是一本关于Linux 命令行与shell 脚本编程的全面教程.全书分为四部分:第一部分介绍Linuxshell 命令行:第二部分介绍shell 脚本编程基础:第三部分深入探讨shell 脚本编程的高级内容:第四部分介绍如何在现实环境中使用shell 脚本.本书不仅涵盖了详尽的动手教程和现实世界中的实用信息,还提供了与所学内容相关的参考信息和背景资料. 本书内容全面,语言简练,示例丰富,适合于linux 系统管理员及Linux 爱好者阅读

《Linux命令行与shell脚本编程大全》学习笔记(转)

第一部分:Linux命令行<Linux命令行与shell脚本编程大全> 第一章:初识Linux shell<Linux命令行与shell脚本编程大全> 第二章:走进shell<Linux命令行与shell脚本编程大全> 第三章:基本的bash shell命令<Linux命令行与shell脚本编程大全> 第四章:更多的bash shell命令<Linux命令行与shell脚本编程大全> 第五章:使用Linux环境变量<Linux命令行与she

Shell脚本编程具体解释

第12章 Shell脚本编程   l  Shell命令行的执行 l  编写.改动权限和运行Shell程序的步骤 l  在Shell程序中使用參数和变量 l  表达式比較.循环结构语句和条件结构语句 l  在Shell程序中使用函数和调用其它Shell程序 12-1   Shell命令行书写规则 u  Shell命令行的书写规则 对Shell命令行基本功能的理解有助于编写更好的Shell程序,在执行Shell命令时多个命令能够在一个命令行上执行,但此时要使用分号(:)分隔命令,比如: [[emai

shell脚本编程高级篇

SHELL脚本编程进阶循环执行:简单来说就是把一些指令重复循环. 循环代码具体的指令有三种: for , while , until其中for, while用的最多.for循环 for 变量名 in 列表;do 循环体 done 关键字的帮助都是用help来查询.for循环语法:在shell编程中 for,in,do,done.这些都是他的关键字,其中循环的指零就放在do和done之间.WORDS决定了循环次数.循环的次数由in 后面跟的WORDS(字符串)的数量决定.字符串的个数决定了do和d