`
qindongliang1922
  • 浏览: 2171989 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
7265517b-f87e-3137-b62c-5c6e30e26109
证道Lucene4
浏览量:117098
097be4a0-491e-39c0-89ff-3456fadf8262
证道Hadoop
浏览量:125444
41c37529-f6d8-32e4-8563-3b42b2712a50
证道shell编程
浏览量:59542
43832365-bc15-3f5d-b3cd-c9161722a70c
ELK修真
浏览量:71028
社区版块
存档分类
最新评论

跟散仙学shell编程(三)

阅读更多
散仙在上一篇文章里写了关于如何使用if-else以及case等流程控制的用法,本篇呢,来看下如何在shell里面使用更多的结构化命令,那么就是我们的循环了。


在shell里面基本的for循环的命令格式:
for var in list
do
   commands
done
[search@h1 fortest]$ cat t1.sh 


for t in i have a dog
do
echo $t
done
[search@h1 fortest]$ sh t1.sh 
i
have
a
dog
[search@h1 fortest]$ 


注意这个t变量,与其他编程语言不通,在for循环外面这个变量仍然有效:

[search@h1 fortest]$ cat t1.sh 


for t in i have a dog
do
echo $t
done


echo -n "t变量是否在循环外有效呢?我们来看看:"

echo $t

t="覆盖t"


echo $t


[search@h1 fortest]$ sh t1.sh 
i
have
a
dog
t变量是否在循环外有效呢?我们来看看:dog
覆盖t
[search@h1 fortest]$ 

默认的shell分隔符是按空格分隔的,这一点需要注意,如果我们的字符串中本身含有空格,或其他特殊符号,有2中解决办法:
(1)用\转义类似单引号或双引号
(2)加上双引号表名是一个整体
[search@h1 fortest]$ cat t2.sh 




for var in "xi an" isn\'t a city
do

echo $var

done
[search@h1 fortest]$ sh t2.sh 
xi an
isn't
a
city
[search@h1 fortest]$ 


从一个变量中读取数据:
[search@h1 fortest]$ cat a.sh 


list="a b c d e"
list=$list" f"


for var in $list

do 
echo $var
done


echo "结束时间:"`date`
[search@h1 fortest]$ sh a.sh 
a
b
c
d
e
f
结束时间:2014年 08月 12日 星期二 03:57:41 CST
[search@h1 fortest]$ 

从一个文本文件里读取值,并打印:
[search@h1 fortest]$ cat b.txt 
中国
日本
美国
法国

[search@h1 fortest]$ cat c.sh 


for var in `cat b.txt`
do
echo $var
done

[search@h1 fortest]$ sh c.sh 
中国
日本
美国
法国
[search@h1 fortest]$ 


更改字段分隔符,默认的环境变量IFS控制内部字段分隔符,默认情况下对空格,制表符,换行符生效:我们可以修改这个值,来临时满足我们的业务需要,目标达成后记得还原其原来的值:

IFS.OLD=$IFS
IFS=$'\N'
<!-- 处理流程,处理完毕后还原 -->
IFS=$IFS.OLD

[search@h1 fortest]$ cat b.txt 
中国 中国2 中国3
日本 日本1 
美国 美国2 美国3
法国 

[search@h1 fortest]$ sh c.sh 
中国
中国2
中国3
日本
日本1
美国
美国2
美国3
法国
[search@h1 fortest]$ cat d.sh 


#修改IFS环境变量分隔符,记得修改完,记得还原

echo "当前的IFS的值: "$IFS

IFSOLD=$IFS
IFS=$'\n'


for var in  `cat b.txt`
do

echo $var

done 


IFS=$IFSOLD


echo "最后还原IFS的值: "$IFS


[search@h1 fortest]$ sh d.sh 
当前的IFS的值: 
中国 中国2 中国3
日本 日本1 
美国 美国2 美国3
法国 
最后还原IFS的值: 
[search@h1 fortest]$ 

学会使用IFS的使用,我们的解析方式就很灵活。
下面使用for循环,遍历目录

[search@h1 ~]$ cat d.sh 


for var in ./*

do

if [  -d "$var" ] ; then
echo "this is dir"$var
elif [  -f "$var" ] ;  then
echo  "this is file"$var
else
echo "i don't know it's type!"
fi

done




echo "end :  "`date`
[search@h1 ~]$ sh d.sh 
this is file./abc1.txt
this is file./abc.xml
this is file./apache-hive-0.13.1-bin.tar.gz
this is file./a.txt
this is file./b.txt
this is file./count.txt
this is file./c.txt
this is file./d.sh
this is dir./filehivebak
this is file./formathadoop.sh
this is dir./fortest
this is dir./hadoop
this is dir./hbase
this is dir./hbase-0.96.2-hadoop2
this is file./hbase-0.96.2-hadoop2-bin.tar.gz
this is dir./hive
this is dir./test
this is file./yarn-site.xml
end :  2014年 08月 12日 星期二 04:26:01 CST
[search@h1 ~]$ 


下面看类C语言的风格,注意双括号之间不需要空格:
[search@h1 fortest]$ cat e.sh 


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

echo "数字: "$i

done 
[search@h1 fortest]$ sh e.sh 
数字: 1
数字: 2
数字: 3
数字: 4
数字: 5
数字: 6
数字: 7
数字: 8
数字: 9
[search@h1 fortest]$ 


使用多个变量:

[search@h1 fortest]$ cat aa.sh 


for (( a=1,b=10; a<=10 ; a++,b--       ))
do

echo "$a    $b"

done
[search@h1 fortest]$ sh aa.sh 
1    10
2    9
3    8
4    7
5    6
6    5
7    4
8    3
9    2
10    1
[search@h1 fortest]$


shell里面的while循环成立的条件是test命令返回的状态码为0的情况,如果非0则退出循环,这一点与其他的编程语言返回true,false不太一样:
[search@h1 fortest]$ cat bb.sh 

var=10
while  [ $var -gt 0 ]
do
echo  $var
var=$[ $var-1 ]

done

[search@h1 fortest]$ sh bb.sh 
10
9
8
7
6
5
4
3
2
1
[search@h1 fortest]$ 


在shell里面还有另外一种循环util,它和while的工作方式相反,只有当状态码返回为0时,循环才会结束:

[search@h1 fortest]$ cat cc.sh 



var=100
until [ $var -eq 0  ]
do

echo  $var
  var=$[ $var - 25 ]
done

[search@h1 fortest]$ sh cc.sh 
100
75
50
25
[search@h1 fortest]$ 



简单看下嵌套for循环:
[search@h1 fortest]$ cat ff.sh 


echo "外层循环一次,内层循环一遍! "

for ((  i=1; i<10 ; i++    ))
do
   echo "我是外层循环: "$i  

   for (( j=1; j<=3 ; j++  ))

   do 
    
   echo "                     我是内层循环: "$j
  
   
   done


done



echo "结束:  "`date`
[search@h1 fortest]$ sh ff.sh 
外层循环一次,内层循环一遍! 
我是外层循环: 1
                     我是内层循环: 1
                     我是内层循环: 2
                     我是内层循环: 3
我是外层循环: 2
                     我是内层循环: 1
                     我是内层循环: 2
                     我是内层循环: 3
我是外层循环: 3
                     我是内层循环: 1
                     我是内层循环: 2
                     我是内层循环: 3
我是外层循环: 4
                     我是内层循环: 1
                     我是内层循环: 2
                     我是内层循环: 3
我是外层循环: 5
                     我是内层循环: 1
                     我是内层循环: 2
                     我是内层循环: 3
我是外层循环: 6
                     我是内层循环: 1
                     我是内层循环: 2
                     我是内层循环: 3
我是外层循环: 7
                     我是内层循环: 1
                     我是内层循环: 2
                     我是内层循环: 3
我是外层循环: 8
                     我是内层循环: 1
                     我是内层循环: 2
                     我是内层循环: 3
我是外层循环: 9
                     我是内层循环: 1
                     我是内层循环: 2
                     我是内层循环: 3
结束:  2014年 08月 12日 星期二 04:50:47 CST
[search@h1 fortest]$ 


下面来看一个小李子实战:
[search@h1 fortest]$ cat hh.sh 



  IFSOLD=$IFS
  IFS=$'\n'


for v in `cat /etc/passwd`
do
  echo  "每一行的值 $v"
#  echo "ifs1:  $IFS"
   IFS=:
#  echo "ifs2:  $IFS"  

 for v2 in $v
   
   do 
         echo "                  按冒号拆分的值:$v2 "
   done


#IFS=$'\n'


done



IFS=$IFSOLD




[search@h1 fortest]$ sh hh.sh 
每一行的值 root:x:0:0:root:/root:/bin/bash
                  按冒号拆分的值:root 
                  按冒号拆分的值:x 
                  按冒号拆分的值:0 
                  按冒号拆分的值:0 
                  按冒号拆分的值:root 
                  按冒号拆分的值:/root 
                  按冒号拆分的值:/bin/bash 
每一行的值 bin:x:1:1:bin:/bin:/sbin/nologin
                  按冒号拆分的值:bin 
                  按冒号拆分的值:x 
                  按冒号拆分的值:1 
                  按冒号拆分的值:1 
                  按冒号拆分的值:bin 
                  按冒号拆分的值:/bin 
                  按冒号拆分的值:/sbin/nologin 
每一行的值 daemon:x:2:2:daemon:/sbin:/sbin/nologin
                  按冒号拆分的值:daemon 
                  按冒号拆分的值:x 
                  按冒号拆分的值:2 
                  按冒号拆分的值:2 
                  按冒号拆分的值:daemon 
                  按冒号拆分的值:/sbin 
                  按冒号拆分的值:/sbin/nologin 
每一行的值 adm:x:3:4:adm:/var/adm:/sbin/nologin
                  按冒号拆分的值:adm 
                  按冒号拆分的值:x 
                  按冒号拆分的值:3 
                  按冒号拆分的值:4 
                  按冒号拆分的值:adm 
                  按冒号拆分的值:/var/adm 
                  按冒号拆分的值:/sbin/nologin 
每一行的值 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
                  按冒号拆分的值:lp 
                  按冒号拆分的值:x 
                  按冒号拆分的值:4 
                  按冒号拆分的值:7 
                  按冒号拆分的值:lp 
                  按冒号拆分的值:/var/spool/lpd 
                  按冒号拆分的值:/sbin/nologin 
每一行的值 sync:x:5:0:sync:/sbin:/bin/sync
                  按冒号拆分的值:sync 
                  按冒号拆分的值:x 
                  按冒号拆分的值:5 
                  按冒号拆分的值:0 
                  按冒号拆分的值:sync 
                  按冒号拆分的值:/sbin 
                  按冒号拆分的值:/bin/sync 
每一行的值 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
                  按冒号拆分的值:shutdown 
                  按冒号拆分的值:x 
                  按冒号拆分的值:6 
                  按冒号拆分的值:0 
                  按冒号拆分的值:shutdown 
                  按冒号拆分的值:/sbin 
                  按冒号拆分的值:/sbin/shutdown 
每一行的值 halt:x:7:0:halt:/sbin:/sbin/halt
                  按冒号拆分的值:halt 
                  按冒号拆分的值:x 
                  按冒号拆分的值:7 
                  按冒号拆分的值:0 
                  按冒号拆分的值:halt 
                  按冒号拆分的值:/sbin 
                  按冒号拆分的值:/sbin/halt 
每一行的值 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
                  按冒号拆分的值:mail 
                  按冒号拆分的值:x 
                  按冒号拆分的值:8 
                  按冒号拆分的值:12 
                  按冒号拆分的值:mail 
                  按冒号拆分的值:/var/spool/mail 
                  按冒号拆分的值:/sbin/nologin 
每一行的值 uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
                  按冒号拆分的值:uucp 
                  按冒号拆分的值:x 
                  按冒号拆分的值:10 
                  按冒号拆分的值:14 
                  按冒号拆分的值:uucp 
                  按冒号拆分的值:/var/spool/uucp 
                  按冒号拆分的值:/sbin/nologin 
每一行的值 operator:x:11:0:operator:/root:/sbin/nologin
                  按冒号拆分的值:operator 
                  按冒号拆分的值:x 
                  按冒号拆分的值:11 
                  按冒号拆分的值:0 
                  按冒号拆分的值:operator 
                  按冒号拆分的值:/root 
                  按冒号拆分的值:/sbin/nologin 
每一行的值 games:x:12:100:games:/usr/games:/sbin/nologin
                  按冒号拆分的值:games 
                  按冒号拆分的值:x 
                  按冒号拆分的值:12 
                  按冒号拆分的值:100 
                  按冒号拆分的值:games 
                  按冒号拆分的值:/usr/games 
                  按冒号拆分的值:/sbin/nologin 
每一行的值 gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
                  按冒号拆分的值:gopher 
                  按冒号拆分的值:x 
                  按冒号拆分的值:13 
                  按冒号拆分的值:30 
                  按冒号拆分的值:gopher 
                  按冒号拆分的值:/var/gopher 
                  按冒号拆分的值:/sbin/nologin 
每一行的值 ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
                  按冒号拆分的值:ftp 
                  按冒号拆分的值:x 
                  按冒号拆分的值:14 
                  按冒号拆分的值:50 
                  按冒号拆分的值:FTP User 
                  按冒号拆分的值:/var/ftp 
                  按冒号拆分的值:/sbin/nologin 
每一行的值 nobody:x:99:99:Nobody:/:/sbin/nologin
                  按冒号拆分的值:nobody 
                  按冒号拆分的值:x 
                  按冒号拆分的值:99 
                  按冒号拆分的值:99 
                  按冒号拆分的值:Nobody 
                  按冒号拆分的值:/ 
                  按冒号拆分的值:/sbin/nologin 
每一行的值 vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
                  按冒号拆分的值:vcsa 
                  按冒号拆分的值:x 
                  按冒号拆分的值:69 
                  按冒号拆分的值:69 
                  按冒号拆分的值:virtual console memory owner 
                  按冒号拆分的值:/dev 
                  按冒号拆分的值:/sbin/nologin 
每一行的值 saslauth:x:499:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
                  按冒号拆分的值:saslauth 
                  按冒号拆分的值:x 
                  按冒号拆分的值:499 
                  按冒号拆分的值:76 
                  按冒号拆分的值:"Saslauthd user" 
                  按冒号拆分的值:/var/empty/saslauth 
                  按冒号拆分的值:/sbin/nologin 
每一行的值 postfix:x:89:89::/var/spool/postfix:/sbin/nologin
                  按冒号拆分的值:postfix 
                  按冒号拆分的值:x 
                  按冒号拆分的值:89 
                  按冒号拆分的值:89 
                  按冒号拆分的值: 
                  按冒号拆分的值:/var/spool/postfix 
                  按冒号拆分的值:/sbin/nologin 
每一行的值 sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
                  按冒号拆分的值:sshd 
                  按冒号拆分的值:x 
                  按冒号拆分的值:74 
                  按冒号拆分的值:74 
                  按冒号拆分的值:Privilege-separated SSH 
                  按冒号拆分的值:/var/empty/sshd 
                  按冒号拆分的值:/sbin/nologin 
每一行的值 mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash
                  按冒号拆分的值:mysql 
                  按冒号拆分的值:x 
                  按冒号拆分的值:27 
                  按冒号拆分的值:27 
                  按冒号拆分的值:MySQL Server 
                  按冒号拆分的值:/var/lib/mysql 
                  按冒号拆分的值:/bin/bash 
每一行的值 search:x:500:500:search,hah,132532,111:/home/search:/bin/bash
                  按冒号拆分的值:search 
                  按冒号拆分的值:x 
                  按冒号拆分的值:500 
                  按冒号拆分的值:500 
                  按冒号拆分的值:search,hah,132532,111 
                  按冒号拆分的值:/home/search 
                  按冒号拆分的值:/bin/bash 
[search@h1 fortest]$ 


除此之外,我们还可以在shell里面使用continue,和break关键字:

[search@h1 fortest]$ cat gg.sh 



for ((  i=1; i<10 ; i++  ))

do
  if (( $i % 2 == 0  )) ;then
  echo   "双数: $i" 
  else
  echo "单数: $i"
  fi
  


done
[search@h1 fortest]$ sh gg.sh 
单数: 1
双数: 2
单数: 3
双数: 4
单数: 5
双数: 6
单数: 7
双数: 8
单数: 9
[search@h1 fortest]$ 


break n n代表结束循环的层数
continue n n代表跳过当前循环的层数
这一点与我们的JAVA不太一样,break用法例子:
[search@h1 fortest]$ cat gg.sh 



for ((  i=1; i<10 ; i++  ))

do
  if (( $i == 7  )) ;then
    echo "结束循环"
    break; 
   
   else
  echo "单数: $i"
  fi
  


done
[search@h1 fortest]$ sh gg.sh 
单数: 1
单数: 2
单数: 3
单数: 4
单数: 5
单数: 6
结束循环
[search@h1 fortest]$ 


下面是continue的用法:
[search@h1 fortest]$ cat gg.sh 



for ((  i=1; i<10 ; i++  ))

do
  if (( $i == 7  )) ;then
    echo "跳过当前循环的值"
  
   continue; 
   else
  echo "数: $i"
  fi
  


done
[search@h1 fortest]$ sh gg.sh 
数: 1
数: 2
数: 3
数: 4
数: 5
数: 6
跳过当前循环的值
数: 8
数: 9
[search@h1 fortest]$ 


最后我们再看下,循环的结果如何重定向到另外一个命令:

[search@h1 fortest]$ cat hx.sh 


echo "使用for循环的结果直接重定向并排序: "
for var in  Brand Abstract China Zokeeber Zabbix Ganglia

do
  echo    "排序后的值是:"$var

done  | sort





[search@h1 fortest]$ sh hx.sh 
使用for循环的结果直接重定向并排序: 
排序后的值是:Abstract
排序后的值是:Brand
排序后的值是:China
排序后的值是:Ganglia
排序后的值是:Zabbix
排序后的值是:Zokeeber
[search@h1 fortest]$ 


下面是结果排序,再写入一个文件里:
[search@h1 fortest]$ cat hx.sh 


echo "使用for循环的结果直接重定向写入一个文件中 "
for var in  Brand Abstract China Zokeeber Zabbix Ganglia

do
  echo    "值是:"$var

done | sort  >> result.txt





[search@h1 fortest]$ sh hx.sh 
使用for循环的结果直接重定向写入一个文件中 
[search@h1 fortest]$ cat result.txt 
值是:Abstract
值是:Brand
值是:China
值是:Ganglia
值是:Zabbix
值是:Zokeeber
[search@h1 fortest]$ 


通过管道命令重定向,我们可以更加容易操作我们的程序!






0
1
分享到:
评论

相关推荐

    跟老男孩学Linux运维:Shell编程实战

    《跟老男孩学Linux运维:Shell编程实战》第三部分为第9章~第13章,着重讲解case条件语句、while循环和until型循环、for循环和select循环、条件与循环控制及程序返回值、Shell数组等知识。《跟老男孩学Linux运维:...

    跟老男孩学Linux运维:Shell编程实战 PDF

    跟老男孩学Linux运维:Shell编程实战 PDF跟老男孩学Linux运维:Shell编程实战 PDF

    跟老男孩学Linux运维:Shell编程实战.pdf 高清 带书签

    资深运维架构实战专家及教育培训界*专家十多年的运维实战经验总结,全面系统地讲解运维工作中Shell编程所需的知识点和Shell编程的各种企业级案例。

    shell编程入门经典--LINUX与UNIX Shell编程指南 (中文pdf版)

    《LINUX与UNIX Shell编程指南》是一本专为初学者设计的shell编程教程,它深入浅出地介绍了在Linux和UNIX系统中如何使用Shell进行高效自动化任务处理。Shell编程是Linux和UNIX系统中的核心技术,它允许用户通过命令行...

    shell编程学习资料

    Shell编程是Linux/Unix系统中不可或缺的一部分,它是一种命令行解释器,允许用户与操作系统进行交互,执行系统命令,以及编写脚本自动化任务。在本文中,我们将深入探讨Shell编程的基础知识,包括基本命令、变量、...

    shell编程指南shell编程指南shell编程指南shell编程指南

    Shell编程是一种在Unix/Linux操作系统环境下进行系统管理与自动化任务的强大工具。它允许用户通过命令行接口执行各种操作,包括文件管理、程序控制、系统管理任务等。本指南将深入探讨Shell编程的基础知识、常用命令...

    Windows Shell 编程.pdf

    Windows Shell 编程.pdf 看过一些对windows 外壳的扩展程序,在使用上一般都是直接利用windows的外壳API做一些工作,因为外壳操作需要一些比较专业的知识,因此,大部分编程人员特别是使用集成编程环境的程序人员对...

    shell编程入门教程+shell脚本专家指南+UNIX.shell编程24小时教程.rar

    《shell编程入门教程》、《shell脚本专家指南》以及《UNIX.shell编程24小时教程》会提供详尽的实例和练习,帮助你巩固所学并深化理解。 总之,Shell编程是Linux/Unix环境中不可或缺的技能,它能够提高工作效率,...

    shell编程题目练习

    shell编程题目练习,练习基本的shell编程,学习脚本语言,提高效率

    跟老男孩学Linux运维:Shell编程实战 完整版 pdf

    跟老男孩学Linux运维:Shell编程实战 完整版 pdf

    Linux与UNIX Shell编程指南.pdf

    "Linux与UNIX Shell编程指南" Linux与UNIX Shell编程指南是计算机科学领域中一本经典的指南手册,旨在帮助读者快速掌握Linux与UNIX操作系统下的shell编程技术。下面是从该书中生成的相关知识点: 1. Shell概述 ...

    Windows Shell 编程指南与实例

    《Windows Shell 编程指南与实例》是一本深入探讨Windows操作系统壳层编程技术的专业书籍。在Windows系统中,Shell指的是用户界面,它为用户提供与操作系统交互的环境,包括桌面、开始菜单、快捷方式等。Shell编程则...

    shell十三问——学习shell编程的好书

    这个“Shell十三问”可能是指一系列关于Shell编程的问题,涵盖了基础到高级的主题。以下是一些关于Shell编程的核心知识点: 1. **什么是Shell**: Shell是一个命令解释器,它接收用户输入的命令并将其转化为操作...

    UNIX命令及SHELL编程

    这是一套完整的Unix培训教材,包括Unix常用命令及SHELL编程基础与高级技巧,PDF格式,共30个文件。另有2个Word文档。包内文件清单如下: 01_Shell-文件安全与权限.PDF 02_Shell-使用find和xargs.PDF 03_Shell-...

    Shell编程高级进阶系列视频.zip

    13Linux下Shell编程之While case演练 14Linux下Shell编程之While case演练 15Shell编程之函数及脚本案例讲解 16Shell编程之函数及脚本案例讲解 17Linux下Shell编程FIND、SED命令实战 18Linux下Shell编程FIND、SED...

    Unix Shell Shell编程

    6本pdf及chm的shell 编程的书 6本pdf及chm的shell 编程的书 6本pdf及chm的shell 编程的书 6本pdf及chm的shell 编程的书 6本pdf及chm的shell 编程的书

    Shell编程中文手册.pdf

    Shell 编程中文手册 本手册涵盖了 Shell 编程的基础知识,包括 Shell 概述、Shell 解析器、Shell 脚本入门、Shell 中的变量等。 Shell 概述 Shell 是一种命令行接口,允许用户与操作系统进行交互。学习 Shell ...

    shell编程个人笔记

    shell编程个人笔记shell编程个人笔记shell编程个人笔记shell编程个人笔记shell编程个人笔记shell编程个人笔记shell编程个人笔记shell编程个人笔记shell编程个人笔记shell编程个人笔记shell编程个人笔记shell编程个人...

    LinuxShell编程基础教程.pdf

    Linux Shell 编程基础教程 本资源为 Linux Shell 编程基础教程,涵盖了 Linux Shell 编程的基础知识,包括语法基本介绍、变量、环境变量、Shell 命令和流程控制等。 一、语法基本介绍 在 Linux Shell 编程中,...

Global site tag (gtag.js) - Google Analytics