(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)-[~/桌面]
└─$ history1 python2 python3 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脚本实践指南 王军
水平有限,难免会有错误的地方,欢迎评论指出。
(2)shell编程学习 Shell中的变量(预设变量表)及变量定义与特殊变量 (脚本小子的进阶之路)相关推荐
- (1)Shell 编程学习 Shell是什么?Shell的浅显原理 为什么要学Shell 及其第一个Shell脚本 CTF角度学习Shell
最近刷CTF题目的时候经常要用到Shell语言,但是自己并没有系统的学习,所以最近花了点时间学习一下,所以重新来梳理一下.对于稍微有一点编程语言基础的同学,能上手Shell其实不需要半小时(甚至更短) ...
- Linux shell编程学习
Linux shell编程学习 shell是一个作为用户与Linux系统间接口的程序,它允许用户向操作系统输入需要执行的命令.这点与Windows的命令提示符类似,但Linux shell的功能更加强 ...
- Shell编程基础---shell的结构、执行及变量
2019独角兽企业重金招聘Python工程师标准>>> 本文索引: shell脚本介绍 shell脚本结构和执行 date命令用法 shell脚本中的变量 shell脚本介绍 she ...
- SHELL编程学习笔记
SHELL编程学习笔记 本文描述unix shell的各种应用实例,根据查阅资料和自我总结,作为自己今后复习的模板.本文搜集整理常用的shell应用实例,以例子详述unixshell部分命令的使用,着 ...
- 《Linux Shell编程学习笔记之一》
<Linux Shell编程学习笔记之一> 前言 由于自己一直在Windows上面编程,用linux用的比较少,学习linux还是本科大二学的一点点知识.因此自己就准备花点时间来熟悉下li ...
- linux shell编程学习——数组使用
linux的shell的编程方面很强大,最近在写脚本的时候,需要用到shell的数组.下面对最近的学习和使用做个简单的总结. 定义 linux的数组分两种,一种是普通的下标数组,一种是关联数组.前者和 ...
- Linux Shell编程学习笔记(4)
Linux Shell编程学习笔记(2015-7-20) 分类:linux shell 今天学习了Linux Shell中的控制结构.其实大多数语言的控制结构这一块都是基本类似的,有了C语言的基础 ...
- Linux Shell编程学习笔记(2)
Linux Shell编程学习笔记(2015-7-12) 分类:linux shell Shell变量 一:关于Shell变量 Shell是一种弱类型的语言,变量存储的一切值都是字符串.Shell ...
- Linux Shell编程学习笔记(3)
Linux Shell编程学习笔记(2015-7-19) 分类:linux shell 一:位置参数和特殊变量 什么是位置参数? 位置参数也叫位置变量,是运行shell脚本程序时,命令行she ...
最新文章
- HDU 4831 Scenic Popularity 暴力模拟
- Spring使用总结
- 待处理,待学习(每日更新)
- FM之SO_DOCUMENT_SEND_API1
- python中深浅复制教程
- Java面试题及答案,java对外提供接口
- oracle 增量设为3 循环_Oracle 差异性增量 和 累计增量 原理(转)
- Super VLAN原理
- 3dmax外挂神器更新了|3dmax外挂在过去几年里,食住玩都更新记录了3dmax外挂的什么功能?
- Fliqlo时钟屏保无毒Windows/Mac版
- 【软考系统架构设计师】2010年下系统架构师案例分析历年真题
- 戴尔计算机更新程序,戴尔电脑如何更新显卡驱动 其实很简单-电脑显卡怎么升级...
- vue视频通话(Agora声网)
- Android源码 SettingsEnums路径
- 怎么把人物模型走路、跑步动画拼接起来
- K_A12_004 基于STM32等单片机采集人体红外感应(HC-SR501)模块串口与OLED0.96双显示
- 03 SpringMVC 处理响应
- scrapy实现二级页面爬取(以小说为例)
- Android Platform Architecture 安卓平台架构
- 【linux】循序渐进学运维-printf