浅谈bash shell 变量

一、简述

变量是指内存空间的命名,指向内存中一个或一组地址。bash shell中的变量属于弱类型变量,使用变量无需声明、不需要指定类型,默认为字符型变量。

二、变量命名、赋值、引用

(1)命名规则:

    1.只能使用字母,数字,下划线;并且不能使用数字开头。

    2.不能使用bash关键字,可用help命令查看,例如:if,for。

    3.见名知意,变量命名人性化,好的命名有助于提升脚步易读性。

    

(2)变量赋值,引用

变量使用等号来赋值;

引用变量时,在变量名前加$,形式有$var,${var},"$var"。像$var这种简便方式容易和上下文混淆变量名

1.当给变量名赋值字符串时,字符串当中不含空格可以不使用引号

~]$ name=tom                #等号两边不能有空格出现
~]$ title="What is Linux?"        #字符串中含有空格,使用引号括起
~]$ title='What is Linux?'

2.变量赋值引用变量时,只能使用弱引用"",使用强引用''不会引用变量值

[root@centos7 ~]$ path="/home/$USER"
[root@centos7 ~]$ echo $path
/home/root
[root@centos7 ~]$ path='/home/$USER'          #使用单引号只会原样赋值
[root@centos7 ~]$ echo $path
/home/$USER

3.变量接收命令结果,使用$()或者反引号` `

[root@centos7 ~]$ userid=$(id -u root)
[root@centos7 ~]$ echo $userid
0
[root@centos7 ~]$ username=`whoami`
[root@centos7 ~]$ echo $username
root

三、变量分类 

按作用范围可划分为:

  1. 局部变量

    生效范围是当前shell中某代码片段,通常指函数中的变量

  2. 本地变量

    生效范围是当前shell进程,及当前shell中(command1;command2;)形式的subshell

  3. 全局变量

    生效范围是当前shell进程,及其子进程

[root@centos7 ~]$ name=tom;echo $name          #定义本地变量name
tom
[root@centos7 ~]$ (echo $name)                 #()形式的subshell可以取得name变量值
tom
[root@centos7 ~]$ (name=bob;echo $name;)       
bob
[root@centos7 ~]$ echo $name                    #重新定义的变量不能传递出来
tom

全局变量  

全局变量的声明方式为:

export variable 或者 declare -x variable       

[root@centos7 ~]$ cat test.sh             #新建一个脚本,看本地变量name是否生效
#!/bin/bash

echo there is subshell
echo name is $name
[root@centos7 ~]$ ./test.sh                 
there is subshell
name is                            #name变量值没有传递进来
[root@centos7 ~]# export name       #将name声明为环境变量
[root@centos7 ~]# ./test.sh 
there is subshell
name is tom                        #name变量值此时生效

查看当前shell环境变量命令为

bash$ env;printenv;declare;

撤销变量命令

bash$ unset variable

定义的环境变量会随着shell退出而失效,可将export variable=value 写入~/.bashrc

四、位置变量,特殊变量

位置变量

$1,$2,$3…用于脚本中,获取通过命令行传递给它的参数

$# 记录命令行参数的个数

$*,$@ 表示所有的参数。当引用所用参数使用""引起时,二者是有区别的,$*将所有参数表示为一个整体,

而$@将所有参数独立表示

[root@centos7 ~]$ cat positionVar.sh      #测试位置参数脚本
#!/bin/bash

echo 1st args is $1
echo 2sec args is $2
echo 3rd args is $3
echo args number is $#
echo all args are $*
echo all args are $@
[root@centos7 ~]$ ./positionVar.sh dog cat fish    #传递三个参数:dog,cat,fish
1st args is dog
2sec args is cat
3rd args is fish
args number is 3
all args are dog cat fish
all args are dog cat fish

测试$*,$@的区别

[root@centos7 ~]# cat positionAll.sh   #新建脚本
#!/bin/bash

echo test '$*'------------
./positionVar.sh "$*"

echo test '$@'------------
./positionVar.sh "$@"
[root@centos7 ~]# ./positionAll.sh dog cat fish   #测试,传递三个参数
test $*------------
1st args is dog cat fish      # $*将多个参数整体传递进来
2sec args is
3rd args is
args number is 1
all args are dog cat fish
all args are dog cat fish
test $@------------
1st args is dog               # $@将多个参数单独传递进来
2sec args is cat
3rd args is fish
args number is 3
all args are dog cat fish
all args are dog cat fish

特殊变量

1.$0 表示执行命令本身

[root@centos7 ~]# ./test.sh 
the script is ./test.sh
[root@centos7 ~]# /root/test.sh 
the script is /root/test.sh

2.$? 表示命令执行状态码;脚本的状态码为最后一条命令的状态码

0 表示执行成功

1-255 表示执行失败

[root@centos7 ~]# ll -d /root
dr-xr-x---. 16 root root 4096 Aug 13 11:34 /root
[root@centos7 ~]# echo $?
0                            #成功
[root@centos7 ~]# ll -d /roots
ls: cannot access /roots: No such file or directory
[root@centos7 ~]# echo $?
2                            #失败
[root@centos7 ~]# lls -d /root
bash: lls: command not found...
Similar command is: 'ls'
[root@centos7 ~]# echo $?
127                           #失败

五、课后作业

1、编写脚本/root/bin/systeminfo.sh,显示当前主机系统信息,包括主机名,IPv4地址,操作系统版本,内核版本,CPU型号,内存大小,硬盘大小。

#!/bin/bash
echo "hostname:`hostname`"
echo -e "IPv4:\n`ifconfig|sed -nr 's/inet (([0-9]{1,3}\.){3}[0-9]{1,3})(.*)/\1/p'`"
echo "OS:`cat /etc/centos-release`"
echo "Kernel:`uname -r`"
echo "CPU:`lscpu|sed -nr s/'Model name:[[:space:]]+\<//p'`"
echo "Memory:`free -m |grep Mem|tr -s ' '|cut -d' ' -f2`M"
echo "Disk:`lsblk|grep disk|tr -s ' '|cut -d' ' -f4`"

2、编写脚本/root/bin/backup.sh,可实现每日将/etc/目录备份到/root/etcYYYY-mm-dd中

#!/bin/bash

echo "backup dir /etc"
cp -a /etc /root/etc`date +%F`
echo "backup finish `date +%F`"

3、编写脚本/root/bin/disk.sh,显示当前硬盘分区中空间利用率最大的值

#!/bin/bash

echo "the max ratio of partiton used is:`df |grep /dev/sd|cut -c 45-46|sort -n|tail -1`%"

4、编写脚本/root/bin/links.sh,显示正连接本主机的每个远程主机的IPv4地址和连接数,并按连接数从大到小排序

#!/bin/bash
echo "links is :`netstat -tn|grep tcp|tr -s ' '|cut -d: -f2|cut -d' ' -f2|sort|uniq -c|sort -nr`"

5、写一个脚本/root/bin/sumid.sh,计算/etc/passwd文件中的第10个用户和第20用户的ID之和

6、写一个脚本/root/bin/sumspace.sh,传递两个文件路径作为参数给脚本,计算这两个文件中所有空白行之和

#!/bin/bash

num1=`grep '^$' $1 |wc -l`
num2=`grep '^$' $2 |wc -l`
echo "sumspace is :$[num1+num2]"

7、写一个脚本/root/bin/sumfile.sh,统计/etc, /var, /usr目录中共有多少个一级子目录和文件

#!/bin/bash

num1=`(ls $1;ls $2;ls $3)|wc -l`
echo "files total :$num1"

8、写一个脚本/root/bin/argsnum.sh,接受一个文件路径作为参数;如果参数个数小于1,则提示用户“至少应该给一个参数”,并立即退出;如果参数个数不小于1,则显示第一个参数所指向的文件中的空白行数

#!/bin/bash
read -p "please input at least one args :" filepath
[[ -n $filepath ]]&&echo "blank lines number:`grep -c '^$' $filepath`"||echo "at least one args"

9、写一个脚本/root/bin/hostping.sh,接受一个主机的IPv4地址做为参数,测试是否可连通。如果能ping通,则提示用户“该IP地址可访问”;如果不可ping通,则提示用户“该IP地址不可访问”

#!/bin/bash
read -p "please input a IPv4:" ipaddr
ping -W1 -c1 $ipaddr &>/dev/null&&echo "the IP is reachble"||echo "the IP is unreachble"

10、判断硬盘的每个分区空间和inode的利用率是否大于80,如果是,发邮件通知root磁盘满

#!/bin/bash
diskmax=`df|grep /dev/sd|cut -c 45-46|sort -n|tail -1`
inodemax=`df -i|grep /dev/sd|cut -c 43-44|sort -n|tail -1`
[[ $diskmax -gt 80 || $inodemax -gt 80 ]]&&mail -s 'disk warning' root /etc/issue||echo "disk space is ok"

11、指定文件做为参数,判断文件是否为.sh后缀,如果是,添加x权限

#!/bin/bash
[ ! -f $1 ]&&echo no such file or not a common file&&exit
[[ $1 =~ .*\.sh$ ]]&&chmod +x $1&&echo chmod +x ok!||echo this is not a shellscript

12、判断输入的IP是否为合法IP

#!/bin/bash
read -p "input a IP:" ipaddr
echo $ipaddr |egrep -q '^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$' &&echo "IP is correct"||echo "IP is illegal"

13、计算1+2+3+…+100

$ seq s + 1 100

14、输入起始值A和最后值B,计算从A+(A+1)…+(B-1)+B的总和

#!/bin/bash

read -p "input a start number:" startnum && grep '^[0-9]+$' $startnum &>/dev/null||echo not a number&&exit
read -p "input a end number:" endnum &&grep '^[0-9]+$' $endnum ||(echo not a number&&exit)
[[ $startnum -ge $endnum ]]&&echo start number greater than end number,illegal||echo sum from start number to end number is:`seq -s + $startnum $endnum|bc`




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

(0)
cutemsyucutemsyu
上一篇 2016-08-15 09:25
下一篇 2016-08-15 09:25

相关推荐

  • 也许你根本不会用百度搜索

    搜索引擎可以帮助使用者在Internet上找到特定的信息,但它们同时也会返回大量无关的信息。但是如果多使用一些技巧,你将发现搜索引擎会花尽可能少的时间找到你需要的确切信息。 1.简单查询 这个就是最简单便捷的使用方式,其实也是我们大多数人平时使用百度或者其他搜索引擎的方式。比如你想查培训学校,那么你的第一反应肯定就是在百度里输入【挖掘机】【挖掘机学校】【蓝翔…

    2015-03-02
  • 马哥教育网络班22期+第五周课程练习

    1、显示当前系统上root、fedora或user1用户的默认shell; [xw@localhost ~]$ cat /etc/passwd | grep -E "^(root|fedora|user1)\>" | cut -d:&…

    Linux干货 2016-10-09
  • N25第1周作业

    1.计算机的组成及功能 地址:博客园http://www.cnblogs.com/qingyangzi/p/6133274.html 2.linux主要的发行版及其区别和联系 地址:博客园http://www.cnblogs.com/qingyangzi/p/6135801.html 3.linux哲学思想 地址:博客园http://www.cnblogs.…

    Linux干货 2016-12-05
  • 系统启动及恢复

    一、知识整理 1、modinfo命令:显示模块的详细描述信息: -n 只显示模块文件路径 -p 显示模块参数 -a auther -d description -l license协议 modprobe命令:装载或卸载内核 -r卸载内核,同rmmod 配置文件:/etc/modprobe.d/*.conf depmod命令:内核模块依赖关系文件及系统信息映射…

    Linux干货 2016-09-22
  • N24_huamao 学习计划

       每天会安排好时间按顺序看视频进行学习,由于基础比较差我会先进行笔记然后再做博客记录。需要操作的知识点会跟着视频和自己的理解去做,最后达到马哥所说的“技能”所需的要求。运维的知识点很广很多也很复杂。当然想学好后边的就要先打好基础从linux系统开始学习把重要的命令记牢应用灵活才可以。这第一步自己一定要迈好。

    Linux干货 2016-10-26
  • 文本处理工具之AWK

    概述:     在之前的文章中,我们介绍过文本处理三剑客的grep、sed,本篇就简要说明下awk的用法。主要是围绕常见的一些用法进行展开,分为以下几个部分:     1、awk的基础语法     2、awk的进阶语法  &nbs…

    Linux干货 2016-09-20

评论列表(1条)

  • 马哥教育
    马哥教育 2016-08-15 10:01

    总结的很好,并且通过实验验证了自己的想法,这对自己理解变量来说,是一个更好的理解方式。