关于shell脚本基础编程第五篇

              shellb编程基础第五篇             
本章内容:数组

变量:存储单个元素的内存空间
数组:存储多个元素的连续的内存空间,相当于多个变量的集合。
索引:编号从0开始,属于数值索引
注意:索引可支持使用自定义的格式,而不仅是数值格式,即为关联索引,bash4.0版本之后开始支持。
bash的数组支持稀疏格式(索引不连续)
 
数组名[索引]
${数组名[索引]}

定义数组:
声明数组:declare -a NAME           声明索引数组
          declare -A
NAME           声明关联数组
数组中元素赋值方式
一次只赋值一个元素:     
一次赋值全部元素         

只赋值特定元素                 
交互式数组值赋值        read -a
数组陈列
===================================================================
一次性元素赋值方式:
[root@xiaomag
~]# declare -a name        声明索引数组名称
[root@xiaomag ~]#
name[0]=xiaobo        数组元素
[root@xiaomag ~]# name[1]=laozai         
数组元素
[root@xiaomag ~]# echo ${name[*]}         调用全部元素
xiaobo laozai

[root@xiaomag ~]# echo ${name[0]}        调用0的元素
xiaobo
[root@xiaomag
~]# echo
${name[1]}        调用1的元素
laozai
===================================================================
一次赋值给全部元素:
[root@xiaomag
~]# name=("xiaobo" "laozai")     数组名称=元素列表
[root@xiaomag ~]# echo
${name[0]}                    输出打印数组0的参数
xiaobo 
[root@xiaomag ~]# echo
${name[1]}                    输出打印数组1的参数
laozai
[root@xiaomag ~]# echo
${name[*]}                     输出打印全部元素
xiaobo
laozai
====================================================================
只给特定元素:
[root@xiaomag
~]# name=([0]="xiaobo" [2]="laozai")   数组名称=特定给元素
[root@xiaomag ~]# echo
${name[0]}            
xiaobo
[root@xiaomag ~]# echo ${name[2]}  

laozai
[root@xiaomag ~]# echo ${name[*]}
xiaobo
laozai                     

====================================================================
命令行举例交互式数组赋值:
[root@Compro
~]# read -a name          读取数组 名称
xiaomag xiaobo
laozai                            写入对应元素
[root@Compro ~]# echo ${name[0]}    
0就是第一个元素
xiaomag
[root@Compro ~]# echo ${name[1]}   
1就是第二个元素
xiaobo
[root@Compro ~]# echo ${name[2]}   
2就是第三个元素
laozai                                                     
这叫做索引数组
======================================================================
[root@xiaomag
~]# name[laozai]=xiaobo   
[root@xiaomag ~]# echo
${name[laozai]}
xiaobo
这种叫做关联数组
=====================================================================
引用数组中的元素 
$ {name[0]} 
注意 :引用时只给数组名,表示引用下标为0的元素
数组的长度,(数组中元素的个数)
${#name[*]}   

${#name[@]}  就加上括号表示元素中的个数
,不加表示第一个元素字符中的个数
=====================================================================
练习
[root@Compro
~]# vim shuzusuiji.sh         
编辑脚本名称
#!/bin/bash                                                
#   

#uesr:Compro
#数组生成10个随机数保存与数组中,并找出其最大值和最小值
declare -a
name                                          声明索引数组 name
declare -i
max=0                                         声明整数属性
for i in {0..9};do    
                                       循环 变量i的值,0-9

 name[$i]=$RANDOM                                数组赋值上条命令的值=随机
 echo
${name[$i]}                                        打印数组的随机值
 [ ${name[$i]}
-gt $max ] && max=${name[$i]}    条件判断打印的值是否大于0.  如果大于0的话就执行 max=数组$i的元素

done
echo "Max:$max"                                       
输出打印上面的$max的值
===================================================
练习
[root@Compro
shuzu]# vim oushuzhihe.sh

#!/bin/bash
#
#user:Compro
#写一个脚本,定义一个数组,数组中的元素是/var/log目录下所有以.log结尾的文件;
要统计其下标为偶数的文件中的行数之和
declare
-a files                                           声明索引数组 files
files=(
/var/log/*.log )                                  数组元素= 路径
declare -i
lines=0                                       声明整数属性

for i in $(seq 0 $[${#files[*]}-1]);do           循环 变量i的值 ,追加数组元素
       
if [ $[$i%2] -eq 0 ];then                      分支判断变量值等于0
                let
lines+=$(wc -l ${files[$i]} | cut -d' ' -f1 )  计算变量值 抽取以空白符为分隔符的第1列的值
       
fi
done
echo "Lines: $lines."                                   
输出打印结果
==============================================================
引用数组中的元素
所有元素:${数组[@]},${数组[*]}
数组切片:${数组[@]}:offset:number
         
offset   要跳过的元素个数
          number   要取出的元素个数
          取偏移量之后的所有元素 
${数组[@]:offset}
向数组中最加元素:
                
数组名称[${#数组元素[*]}]
删除数组中的某元素:导致稀疏格式
                   unset
数组[索引]
关联数组:
        declare -A 数组名称       必选先声明,在调用
       
数组名称=([元素1]='val1' [元素2] 'val2'…)

========================================================================

               bash 的字符串处理工具
字符串切片:
     ${#var}     返回字符串变量var的长度     

     ${var:offset}
offset返回字符串的变量var中第offset个字符后(不包括第offset个字符)的字符开始,
                         
到最后的部分offset的取值在0到 ${#var}-1 之间(bash4.2后,允许为负值)
     ${var:offset:number} 
返回字符串变量var中从第offset个字符 后(不包括第offset个字符)
                               
的字符开始,长度为number的部分
     ${var: -数字} 取字符串的最右侧几个字符
                       
 注意:冒号后面必须有一个空白字符      
[root@xiaomag ~]# var=`echo {a..z}`
[root@xiaomag
~]# v=`echo $var |tr -d " "`
[root@xiaomag ~]# echo
$v
abcdefghijklmnopqrstuvwxyz
[root@xiaomag ~]# echo
${#v}
26
[root@xiaomag ~]# echo
${v:3}
defghijklmnopqrstuvwxyz
[root@xiaomag ~]# echo
${v:3:5}
defgh
[root@xiaomag ~]# echo ${v:
-3}
xyz
=====================================================================                                                                                            

基于模式取字符串:
                           ${var#*word}    其中word可以是指定的任意字符

                          
 功能:自左而右,查找var变量所存储的字符串中,第一次出现word,
                                        
删除字符串开头至第一次出现word字符之间的所有字符
                           ~]# echo
${v#*m}
                                  
nopqrstuvwxyz
                           ${var##*word}  
同上,不同的是,删除的是字符串开头至

                                                       最后一次由word指定的字符之间的所有内容
                          
~]# file="/var/log/messages"
                           ~]# echo
${file##*/}
                                
messages     
                           ${var%word*}   
其中word可以是指定的任意字符
                           
功能:自右而左,查找var变脸所存储的字符串中,第一次出现的word,
                                      
 删除字符串最后一个字符向左至第一次出现word字符之间的所有字符
                            ~]#
file="/var/log/messages"
                            ~]# echo
${file%/*}
                                  /var/log

                           ${var%%word*}   同上,只不过删除字符串最右侧的字符向左至

                                                        
最后一次出现word字符之间的所有字符
                           
url=aaaa:5556:222
                            ~]# echo ${url##*:} 

                                   222      
最右侧的
                            ~]# echo ${url%%:*}

                                  aaaa      最左侧的
[root@Compro ~]#
var=hacker:x:1005:1005:hacker,,38763415:/home/hacker:/bin/bash
[root@Compro
~]# echo
$var
hacker:x:1005:1005:hacker,,38763415:/home/hacker:/bin/bash
[root@Compro
~]# echo
${var#*x}
:1005:1005:hacker,,38763415:/home/hacker:/bin/bash
==============================================================================
查找替换:
       
${var/pattern/substi} : 查找var所表示的字符串,第一次被pattern所匹配到的字符串,以路径替换之
       
${var//pattern/substi} : 查找var所表示的字符串,所有被pattern所匹配到的字符串,以路径替换之
       
${var/#pattern/substi} : 查找var所表示的字符串,行首被pattern所匹配到的字符串,以路径替换之
       
${var/%pattern/substi} : 查找var所表示的字符串,行尾被pattern所匹配到的字符串,以路径替换之查找并删除:
       
${var/pattern}   查找var所表示的字符串中,删除第一次被pattern所匹配到的字符串
    

        ${var//pattern}  所有 
        ${var/#pattern}  行首
       
${var/%pattern}  行尾
字符大小写转换:
        ${var^^} 
把var中的所有小写字母转换为大写
        ${var,,}  把var中的所有大写字母转换为小写       

变量赋值:
        ${var:-value}      
如果var为空或未设置,那么返回value;否则,则返回var的值
        ${var:+value}     
如果var不空,则返回value
        ${var:=value}      如果var为空或未设置,那么返回value,并将value
赋值给var;f否则,则返回var的值
        ${var:?error_info}  
如果var为空或未设置,那么返回error_info;否则,

                                         
则返回var的值为脚本程序使用配置文件,实现变量赋值
        定义文本文件,每行定义“name=value”
       
在脚本中source此文件即可

高级变量用法-有类型变量:
                                            
shell变量一般是无类型的,但是bash
shell提供了declare和
                                           
 typeset两个命令用于指定变量的类型,两个命令是完全等价的
declare [选项] 变量名
               -r   
name    将变量设置为只读属性
               -i    name    将变量定义为整型数
              
-a   name    将变量定义为数组
               -f    name   
显示此脚本前定义过的所有函数名及其内容
               -F  name   
仅显示此脚本前定义过的所有函数名
               -x   name    将变量声明为环境变量
              
-l    name    将变量转为小写字母                            

==============================================================      

间接变量引用:
                       
如果第一个变量的值是第二个变量的名字,
                        从第一个变量引用第二个变量的值就称为间接变量引用

var1=var2
var2=var3
var1的是是var2,而var2又是变量名,var2的值为var3,间接变量引用是指通过var1获得不变量值var3的行为
[root@Compro
~]# echo ${!var1}    第一种间接引用格式
var3
bash
shell提供了两种格式实现间接变量引用
[root@Compro ~]# n=name
[root@Compro ~]#
name=xiaomag
[root@Compro ~]# n1=${!n}
[root@Compro ~]# echo
$n1
xiaomag
[root@Compro ~]# eval n3=\$$v1    第二种间接引用格式
[root@Compro
~]# echo
$n3
xiaomag
===============================================================          

eval命令
将会首先扫描命令行进行所有的置换,然后在执行该命令。
改名了适用于那些一次扫描无法实现其功能的变量,该命令对变量进行两次扫描
示例:
[root@Compro
~]# cmd=whoami
[root@Compro ~]# echo $cmd
whoami
[root@Compro ~]# eval
$cmd
root     

=================================================================      

创建临时文件
mktemp命令  创建的临时文件可避免冲突
mktemo 选项 格式filename.XXX  
X至少要出现三个
               -d  创建临时目录
               -p  Dir  
指明临时文件所存放目录位置
[root@Compro ~]# mktemp test.XXX   XXX生成随机字符
test.6Gk      
执行结果
[root@Compro ~]# mktemp /tmp/test.XXX
/tmp/test.631
[root@Compro
~]# ll /tmp/test.631
-rw——-. 1 root root 0 8月  23 14:28
/tmp/test.631
================================================================
安装复制文件
install命令:
          
install [选项] -t  directory=目录来源 将源文件所有参数复制到指定目录
           install [选项] -T 
来源   directory 将目标文件视为普通文件
           install [选项] -d  directory
创建空目录
                    -m mode 默认755
                    -o
owner
                    -g group
举例:
[root@Compro ~]# install -m 700
-o hacker -g hacker file1 file2    将file复制到file2 并且带有700的权限
rwx——.  1
hacker hacker      257 8月  23 20:50
file2                      执行结果
[root@Compro ~]# install -m 700 -d
/testdir/installdir                       创建空目录 给上700权限
[root@Compro ~]# ll
/testdir
总用量 0
drwx——. 2 root root 6 8月  23 20:56
installdir                                 
执行结果
================================================================================
bash如何展开命令行执行:
                    
1 把命令行分成单个命令词
                     2 展开别名
                     3 展开大括号中的声明
( {} )
                     4 展开波浪符声明( ~ )
                     5 命令替换$()
和 “
                     6 再次把命令行分成命令词
                     7
展开文件通配(*、?、[abc]等等)
                     8 准备I/O重定向(<
、>)
                     9 运行命令
防止扩展:
        
单引号(')防止所有扩展
         双引号(")也防止所有扩展但是一下情况例外
         $ (美元符号) 
变量扩展
         ` (反引号)    命令替换
         \ (反斜线)    禁止单个字符扩展
         !
(叹号)      历史命令替换
         反斜线(\)会使随后的字符按愿意解释

bash的配置文件:按生效范围划分,存在两类
全局配置:
         /etc/profile
        
/etc/profile.d/*.sh            
         /etc/bashrc

个人配置:
         ~/.bash_profile
         ~/.bashrc

shell登录两种方式:
交互式登录:
           1 直接通过终端输入帐号密码登录
           2 使用 su –
username  切换的用户
执行顺序:/etc/profile –> /etc/profile.d/*.sh –>
~/.bash_profile –> ~/.bashrc –>/etc/bashrc
非交互式登录:
            1
su username
            2 图形界面下打开的终端
            3 执行脚本
执行顺序:~/.bashrc
–> /etc/bashrc –> /etc/profile.d/*.sh             

profile为交互式登录的shell提供配置
全局:/etc/profile    
/etc/profile.d/*.sh             
个人:~/.bash_profile
功能:用于定义环境变量 ;
运行命令或脚本
bashrc
为非交互式和交互式登录的shell提供配置
全局:/etc/bashrc
个人:~/.bashrc
功能:定义命令别名和函数 ;
定义本地变量

修改profile和bashrc文件后需要生效方法有两种
    重新启动shell进程
    . 或 source

bash
退出任务
保存在~/.bash_logout文件中(用户)
在退出登录shell时运行
可以用于:
    创建自动备份
    清楚临时文件

 

 

 

 

 

 

 

 

 

 

 

 

 

       

原创文章,作者:小马哥,如若转载,请注明出处:http://www.178linux.com/39530

(0)
上一篇 2016-08-24 21:22
下一篇 2016-08-24 21:22

相关推荐

  • 一起学DHCP系列(五)指派、获取

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://jeffyyko.blog.51cto.com/28563/163168     本节将主要讲述DHCP客户端获取IP的过程,也是此系列中非常重要的一节。   &…

    Linux干货 2015-03-25
  • 记事本操作的小小小技巧

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://jeffyyko.blog.51cto.com/28563/140063       大家在查看文本文件的时候,如果内容很多,想快速到达某一位置可能比较麻烦,这时如果按住shift,再点击右侧…

    Linux干货 2015-03-26
  • 海量数据处理算法—Bloom Filter

    1. Bloom-Filter算法简介         Bloom-Filter,即布隆过滤器,1970年由Bloom中提出。它可以用于检索一个元素是否在一个集合中。        Bloom Filter(BF)是一种空间效率很高的随机数据结构,它利用位数组很简洁地表…

    Linux干货 2015-10-22
  • jobs简介

    jobs简介     jobs可以显示当前shell 环境中已启动的作业状态。     用linux的时候经常会碰到类似这种情形,复制,下载一个很大的文件或编辑一个文件,任务占据着界面不能做其他操作,这个时候想不暂停或中止任务去做别的操作就可以将正在执行的命令送往后台去运行。 作业:作业号     …

    Linux干货 2015-05-23
  • vfork 挂掉的一个问题

    在知乎上,有个人问了这样的一个问题——为什么vfork的子进程里用return,整个程序会挂掉,而且exit()不会?并给出了如下的代码,下面的代码一运行就挂掉了,但如果把子进程的return改成exit(0)就没事。 我受邀后本来不想回答这个问题的,因为这个问题明显就是RTFM的事,后来,发现这个问题放在那里好长时间,而挂在下面的几个答案又跑偏得比较严重,…

    Linux干货 2016-08-15
  • 一点点RPM

    1、软件管理器简介          随着Linux的不断发展及越来越多的人投入到Linux大家庭中,软件管理器的作用对于还无法熟练掌握源码编译安装的人们还是显得尤为重要,同时,由Linux开发商在为其编译完成的软件包在某种程度上要比在网络上流传的软件包要安全的多;所以,掌握Li…

    Linux干货 2015-12-06