(2)shell编程学习 Shell中的变量(预设变量表)及变量定义与特殊变量 (脚本小子的进阶之路)

这里尽量以较简略的篇幅讲解,如果之前有Python PHP语言基础的话,学习应该非常快。当然文章篇幅有限,只能讲一些主要的地方,一些偏的知识可能不讲。

目录

变量

局部变量

环境变量

自定义环境变量

系统预设环境变量(这个标题下面的都是)

变量:BASH

变量:BASH_VERSION

 变量:CDPATH

变量:EUID

变量:FUNCNAME

变量:HISCMD

变量:HISTFILE

变量:HISTFILESIZE

变量:HISTSIZE

变量:HOSTNAME

变量:HOSTTYPE

变量:MACHTYPE

变量:LANG

变量:PWD

变量:OLDPWD

变量:PATH

其他预设变量

变量命名

取消变量

特殊变量


变量

顾名思义,变量就是其值可以变化的量。变量名是指向一片用于存储数据的内存空间。变量有局部变量,环境变量这份。

Shell变量是一种弱类型的变量,不像在C语言中,变量必须要先声明再使用。)

tips:Shell中变量名区分大小写

局部变量

局部变量就是指在某个Shell中生效的变量,对其他Shell来说无效。

比如:建立1.sh 2.sh 2个文件

  • 在 1.sh 声明 var=1 ,再用echo $var 输出 。可以看到输出1
  • 在 2.sh echo $var输出,结果为空。

var变量只作用在1.sh文件中。

每个Shell文件运行时都处于一个单独的进程中,独自分配内存空间。

环境变量

环境变量又称为全局变量。大家可以边学边和局部变量比较。

环境变量又分为2类

  • 自定义环境变量
  • 系统预设的环境变量

自定义环境变量

下面做一个套娃实验。

知识点:bash命令:在这个shell创建一个子shell,子shell可以继承父Shell的自定义环境变量。

可以看到,子Shell继承了父Shell的环境变量。(我们打开终端就是打开了一个shell)。另外要说的是,只能子Shell继承父Shell的,在子Shell定义的环境变量,父Shell不能引用。

系统预设环境变量(这个标题下面的都是)

bash(这里可以把bash理解为系统)中默认包含又几十个预设的环境变量,这里只介绍一些常用的。(不一定要一个一个学,有印象就行)

变量:BASH

edg㉿EDG)-[~/桌面]
└─$ echo $BASH
/usr/bin/bash
说明:BASH Shell的全路径

变量:BASH_VERSION

(edg㉿EDG)-[~/桌面]
└─$ echo $BASH_VERSION
5.1.8(1)-release
说明:Bash Shell的版本

 变量:CDPATH

edg㉿EDG)-[~/桌面]
└─$ cd /boot/grub/fonts/    
普通的cd命令                                             1 ⨯
                                                                             
┌──(edg㉿EDG)-[/boot/grub/fonts]
└─$ CDPATH="/boot/grub"
将这个路径定义为环境变量
                                                                             
┌──(edg㉿EDG)-[/boot/grub/fonts]
└─$ cd fonts            
/boot/grub/fonts
这样就可以直接进入了
说明:用于快速进入某个目录。在Linux管理中我们可能要经常要进入各种复杂的目录修改文件,使用CDPATH函数可以很方便的给我们进入相应目录。

变量:EUID

(edg㉿EDG)-[/boot/grub/fonts]
└─$ echo $EUID        
1000
说明:记录当前用户的UID,也就是在使用这个shell界面的用户。

变量:FUNCNAME

先创建一个funcname.sh文件

(edg㉿EDG)-[~/桌面]
└─$ nano funcname.sh
#!/bin/bash
funcname() {
        echo $FUNCNAME
}
funcname
(edg㉿EDG)-[~/桌面]
└─$ bash funcname.sh
funcname

说明:在函数体内部,记录当前函数体的函数名。 

变量:HISCMD

edg㉿EDG)-[~/桌面]
└─$ echo $HISTCMD
211

说明:我们下一条命令是第211条命令,(echo $HISTCMD)这是第210条。
用history可以看到我们历史输入命令
edg㉿EDG)-[~/桌面]
└─$ history
    1  python
    2  python
    3  python3
。。。。。。。。。。。。省略200条

变量:HISTFILE

(edg㉿EDG)-[~/桌面]
└─$ echo $HISTFILE
/home/edg/.bash_history
说明:改文件下记录该用户运行过的命令历史记录。

变量:HISTFILESIZE

(edg㉿EDG)-[~/桌面]
└─$ echo $HISTFILESIZE
2000
说明:设置HISTFILESIZE 文件记录命令的行数。如果任凭HISTFILE文件不断增大,显然会有一天这个文件将大到不可收拾,而且也没有必要记录那么多命令,所以使用某种机制限制该文件的大小是非常有必要的。

变量:HISTSIZE

(edg㉿EDG)-[~/桌面]
└─$ echo $HISTSIZE
1000
说明:记录命令的缓冲区大小,实际上Linux不会每次运行一个命令后立即将该命令记录到HISTFILE文件中。因为Shell采用了“命令缓存区”来记录所有已运行过的命令,在缓存区慢或退出Shell时才将缓冲区的记录写到HISTFILE文件中。

变量:HOSTNAME

edg㉿EDG)-[~/桌面]
└─$ echo $HOSTNAME
EDG
说明:很简单,展示主机名。

变量:HOSTTYPE

edg㉿EDG)-[~/桌面]
└─$ echo $HOSTTYPE
x86_64
说明:展示主机的架构,本机是x86_64

变量:MACHTYPE

edg㉿EDG)-[~/桌面]
└─$ echo $MACHTYPE
x86_64-pc-linux-gnu
说明:主机类型的GNU标识,这种标识有统一的结构。一般来说是“主机架构-公司-系统-gnu”

变量:LANG

edg㉿EDG)-[~/桌面]
└─$ echo $LANG
zh_CN.UTF-8
说明:设置当前系统的语言环境

变量:PWD

(edg㉿EDG)-[~/桌面]
└─$ echo $PWD
/home/edg/桌面
说明:记录当前目录

变量:OLDPWD

(edg㉿EDG)-[~/桌面]
└─$ echo $OLDPWD
/home/edg/桌面
说明:记录之前目录,这个值是什么由之前所在的那个目录决定

变量:PATH

edg㉿EDG)-[~/桌面]
└─$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games
说明:PATH代表命令的搜索路径,非常重要。

其他预设变量

BASH_ENV  一般该值为空。如果该变量在调用脚本时已经设置,它的值将被展开,并用作在执行脚本前读取的启动文件名。 BASH_VERSINFO 一个只读变量数组,保存bash的版本信息 COLUMNS 决定select内建命令打印选择列表的宽度

COMP_LINE

当前命令行 COMP_POINT 相对于当前命令七点的当前光标位置 COMP_WORDS 由当前命令行中单个词组成的变量数组 DIRSTACK 保存当前目录栈内容的变量数组 GLOBIGNORE 由冒号分隔的在补全文件名时要忽略的文件名 GROUPS 一个数组变量,包含当前用户作为成员组的列表 HISTCONTRAL 定义一个命令是否加入历史列表中 IGNOREEOF 控制Shell接受EOF字符作为独立输入的行为 INPUTRC readline初始化文件的名称,取代默认值/etc、inputrc LC_ALL 如果该变量设置了,则这个变量将覆盖LANG的值 LC_CTYPE 决定在文件民咱开和模板匹配里字符的解释和字符集的行为 LINENO 当前执行脚本或者Shell函数的行数 PIPESTATUS 最近运行过的前台管道进程的退出状态值的列表 PPID Shell父进程的进程ID PS3 这个变量的值被用作select命令的提示符 PS4 在命令行前打印的提示符 RANDOM 生成一个0~32767的随机整数 REPLY 内建命令read的默认值 SECONDS Shell运行的秒数 SHELLOPTS 由冒号分隔的Shell已经启用的选项列表 SHLVL 每新增一个Shell进程,该值就增加1 TMOUT 作为内建命令read的默认超时时间。当Shell处于交互状态时,这个值表示等待在基本提示串后输入的秒数 UID 当前用户的真实用户ID

变量命名

不多叙述,只说要点

  • 字母或下划线开头
  • Shell变量区分大小写
  • 变量名和变量值之间用等号紧紧相连,之间没有任何空格
  • 当变量名中有空格时必须用引号括起,否则会出现错误,其中的引号可以是单引号也可以是双引号
  • 如果变量值引用的是其他变量,则必须使用双引号。因为单引号会阻止Shell解释特殊字符¥
  • 使用${}获取变量值是一种相对比较保险的方式

如下图:本来是想输入 人名+Hello的 结果 输出的是nameHello变量,该变量未定义,所以输出为空,但是将我们定义的变量name用括号括起来后,我们的目的就达到了。

edg㉿EDG)-[~/桌面]
└─$ name="Bob"                                                               
┌──(edg㉿EDG)-[~/桌面]
└─$ echo $nameHello                                                          

┌──(edg㉿EDG)-[~/桌面]
└─$ echo ${name}Hello
BobHello

取消变量

使用unset命令 后面+变量  (这里变量也可以是函数名)

─(edg㉿EDG)-[~/桌面]
└─$ name=Bob
┌──(edg㉿EDG)-[~/桌面]
└─$ echo $name
Bob
┌──(edg㉿EDG)-[~/桌面]
└─$ unset name
┌──(edg㉿EDG)-[~/桌面]
└─$ echo $name

(上面的示例可以看到name变量被取消了,我之前在学习其他语言的时候并没有学到取消变量的操作,也可能是因为我菜)

特殊变量

1.位置参数

Shell中还有一些预先定义的特殊只读变量,他们的值只有在脚本运行时才能确认。首先是”位置参数“,位置参数的命名简单直接,比如,脚本本身为$0,第一个参数为$1,第二个参数为$2,第三个为$3,以此类推。当位置参数的个数大于9时,需要用${}括起来标识,比如说第十个位置参数应该记为${10}。另外,$#表示脚本参数的个数总和,$@或$*表示脚本的所有参数。下面的示例脚本使用了这些特殊的位置参数,请注意不同位置的输出。

创建一个 teshu.sh文件 写入:

#!/bin/bash
echo "This script's name is :$0"
echo "S# parameters in total"
echo "All parameters list as:$@"
echo "The first parameter is $1"
echo "The second parameter is $2"
echo "The third parameter is $3"

运行

edg㉿EDG)-[~/桌面]
└─$ bash teshu.sh para1 para2 para3
This script's name is :teshu.sh
S# parameters in total
All parameters list as:para1 para2 para3
The first parameter is para1
The second parameter is para2
The third parameter is para3

2.脚本或命令返回值:$?

在管理员登录到系统中交互式的输入命令时,系统也会及时在屏幕上输出内容给予反馈,比如说本想使用ifconfig查看网卡状态,但是将命令错写成了ipconfig(哈哈),系统会立刻给出command not found 的提示,这种提示确认能让管理员感觉到系统非常”友好“。

但是,有很多后台脚本是需要每天自动运行的,比如每天凌晨两点的数据库备份。在这种情况下一旦出错是不可能在第一时间知道的。那靠什么判断出错了呢?

再考虑一个场景:有些自动备份脚本在按时完成本地数据备份后,还会复制一份放在远程主机上(通过scp就可以做到)。不过在复制前需要先确认远程主机是否”活着“,这可以通过ping远程主机做到。如果能ping通则进行复制,如果ping不同则采取其他动作。这里如何判断是否ping成功了呢?

这时就需要借助命令的返回值来判断了。Linux中判断正常退出的命令和脚本应该以0作为其返回值,任何非0的返回值都表示命令未正确退出或未正常执行。

(edg㉿EDG)-[~/桌面]
└─$ ping 192.161.13.12                                                   2 ⨯
PING 192.161.13.12 (192.161.13.12) 56(84) bytes of data.



^C
--- 192.161.13.12 ping statistics ---
10 packets transmitted, 0 received, 100% packet loss, time 9235ms

                                                                             
┌──(edg㉿EDG)-[~/桌面]
└─$ echo $?                                                              1 ⨯
1

随便输入个错误ip,ping不通 返回1

所以在自动化脚本中,可以通过$?变量的值判断之前命令的执行状态,从而采取不同的动作。

总结

手打这些字,和打这么多例子真是眼睛疼,其实今天还有一些细节,比如数组,转义和引用,实在是没力气打了(内容都看了)下次直接进行脚本编写学习,从例子开始学。

参考书籍

Linux系统命令及Shell脚本实践指南 王军


水平有限,难免会有错误的地方,欢迎评论指出。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值