shell基础之变量及表达式
本节内容
1. shell变量简介
2. 定义变量
3. 使用变量
4. 修改变量的值
5. 单引号和双引号的区别
6. 将命令的结果赋值给变量
7. 删除变量
8. 变量类型
9. 特殊变量列表
10. 退出状态
11. shell表达式与运算符
11.1 条件表达式
11.2 整数比较符
11.3 字符串比较符
11.4 文件测试
11.5 布尔运算符
11.6 逻辑判断符
11.7 整数运算
11.8 其他运算工具
11.9 shell括号用途总结
一、shell变量简介
变量是任何一种编程语言都必不可少的组成部分,变量用来存放各种数据。脚本语言在定义变量时通常不需要指明类型,直接赋值就可以,Shell变量也遵循这个规则。
在Bash shell中,每一个变量的值都是字符串,无论你给变量赋值时有没有使用引号,值都会以字符串的形式存储。这意味着,Bash shell在默认情况下不会区分变量类型,即使你将整数和小数赋值给变量,它们也会被视为字符串,这一点和大部分的编程语言不同。
二、定义变量
Shell 支持以下三种定义变量的方式:
variable=value
variable='value'
variable="value"
variable是变量名,value是赋给变量的值。如果value不包含任何空白符(例如空格、Tab缩进等),那么可以不使用引号;如果value包含了空白符,那么就必须使用引号包围起来。使用单引号和使用双引号也是有区别的,稍后我们会详细说明。
注意,赋值号的周围不能有空格,这可能和你熟悉的大部分编程语言都不一样。
Shell变量的命名规范和大部分编程语言都一样:
(1)变量名由数字、字母、下划线组成;
(2)必须以字母或者下划线开头;
(3)不能使用 Shell 里的关键字(通过 help 命令可以查看保留关键字)。
三、使用变量
使用一个定义过的变量,只要在变量名前面加美元符号$即可,如:
author="ken"
echo $author
echo ${author}
变量名外面的花括号{ }是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:
skill="Java"
echo "I am good at ${skill}Script"
如果不给skill变量加花括号,写成echo "I am good at $skillScript",解释器就会把$skillScript当成一个变量(其值为空),代码执行结果就不是我们期望的样子了。
推荐给所有变量加上花括号{ },这是个良好的编程习惯。
四、系统变量
在命令行提示符直接执行env、set 查看系统或环境变量。env 显示用户环境变量,set 显示Shell预先定义好的变量以及用户变量。可以通过 export 导出成用户变量。一些写 Shell 脚本时常用的系统变量:
$SHELL |
默认 Shell |
$HOME |
当前用户家目录 |
$IFS |
内部字段分隔符 |
$LANG |
默认语言 |
$PATH |
默认可执行程序路径 |
$PWD |
当前目录 |
$UID |
当前用户 ID |
$USER |
当前用户 |
$HISTSIZE |
历史命令大小,可通过 HISTTIMEFORMAT 变量设置命令执行时间 |
$RANDOM(random随机) |
随机生成一个0至32767的整数 |
$HOSTNAME |
主机名 |
普通变量与临时环境变量:
普通变量定义:VAR=value
临时环境变量定义:export VAR=value
变量引用:$VAR
下面看下他们之间区别:
Shell 进程的环境变量作用域是 Shell 进程,当 export 导入到系统变量时,则作用域是 Shell 进程及其 Shell 子进程,另开shell无效。
五、修改变量的值
已定义的变量,可以被重新赋值,如:
url="http://www.baidu.com"
echo ${url}
url="http://www.sina.com"
echo ${url}
第二次对变量赋值时不能在变量名前加$,只有在使用变量时才能加$。
六、单引号和双引号的区别
前面我们还留下一个疑问,定义变量时,变量的值可以由单引号' '包围,也可以由双引号" "包围,它们到底有什么区别呢?不妨以下面的代码为例来说明:
#!/bin/bash
url="http://c.biancheng.net"
website1='C语言中文网:${url}'
website2="C语言中文网:${url}"
echo $website1
echo $website2
运行结果:
C语言中文网:${url}
C语言中文网:http://c.biancheng.net
以单引号' '包围变量的值时,单引号里面是什么就输出什么,即使内容中有变量和命令(命令需要反引起来)也会把它们原样输出。这种方式比较适合定义显示纯字符串的情况,即不希望解析变量、命令等的场景。
以双引号" "包围变量的值时,输出时会先解析里面的变量和命令,而不是把双引号中的变量名和命令原样输出。这种方式比较适合字符串中附带有变量和命令并且想将其解析后再输出的变量定义。
建议:如果变量的内容是数字,那么可以不加引号;如果真的需要原样输出就加单引号;其他没有特别要求的字符串等最好都加上双引号,定义变量时加双引号是最常见的使用场景。
七、将命令的结果赋值给变量
Shell 也支持将命令的执行结果赋值给变量,常见的有以下两种方式:
variable=`command`
variable=$(command)
第一种方式把命令用反引号包围起来,反引号和单引号非常相似,容易产生混淆,所以不推荐使用这种方式;第二种方式把命令用$( )包围起来,区分更加明显,所以推荐使用这种方式。
例如,我创建了一个名为 test 的文本文件。下面的代码中,使用 cat 命令将 log.txt 的内容读取出来,并赋值给一个变量,然后使用 echo 命令输出。
[root@ken ~]# echo "this is ken" > test
[root@ken ~]# mes=`cat test`
[root@ken ~]# echo $mes
this is ken
八、删除变量
使用 unset 命令可以删除变量。语法:
unset variable_name
变量被删除后不能再次使用;unset 命令不能删除只读变量。
举个例子:
#!/bin/bash
myUrl="http://see.xidian.edu.cn/cpp/u/xitong/"
unset myUrl
echo $myUrl
上面的脚本没有任何输出。
定义只读变量
[root@ken ~]# name=ken
[root@ken ~]# readonly name
[root@ken ~]# echo $name
ken
[root@ken ~]# unset name
-bash: unset: name: cannot unset: readonly variable
九、变量类型
运行shell时,会同时存在三种变量:
1) 局部变量
局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
2) 环境变量
所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
3) shell变量
shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
十、特殊变量列表(shell变量)
变量 |
含义 |
$0 |
当前脚本的文件名 |
$n |
传递给脚本或函数的参数。n是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。 |
$# |
传递给脚本或函数的参数个数。 |
$* |
传递给脚本或函数的所有参数。 |
$? |
上个命令的退出状态,或函数的返回值。 |
$$ |
当前Shell进程ID。对于Shell脚本,就是这些脚本所在的进程ID。 |
例子:
#!/bin/bash
echo "File Name: $0"
echo "First Parameter : $1"
echo "First Parameter : $2"
echo "Quoted Values: $@"
echo "Quoted Values: $*"
echo "Total Number of Parameters : $#"
运行结果:
[root@ren5 ~]# bash test.sh name age
File Name: test.sh
First Parameter : name
First Parameter : age
Quoted Values: name age
Quoted Values: name age
Total Number of Parameters : 2
十一、退出状态
$? 可以获取上一个命令的退出状态。所谓退出状态,就是上一个命令执行后的返回结果。退出状态是一个数字,一般情况下,大部分命令执行成功会返回 0,失败返回 1。不过,也有一些命令返回其他值,表示不同类型的错误。
例子:
[root@ren5 ~]# echo ren
ren
[root@ren5 ~]# echo $?
0
[root@ren5 ~]# systemctl restart ab
Failed to restart ab.service: Unit not found.
[root@ren5 ~]# echo $?
5
十二、shell表达式与运算符
1、条件表达式
表达式 |
实例 |
[ expression ] |
[ 1 -eq 1 ] |
[[ expression ]] |
[[ 1 -eq 1 ]] |
test expression |
test 1 -eq 1 ,等同于[ ] |
[root@ren5 ~]# [ 1 -gt 2 ] && echo "this is true" || echo "this is false"
this is false
[root@ren5 ~]# [ 4 -gt 2 ] && echo "this is true" || echo "this is false"
this is true
注意:括号中的表达式前后都有空格,否则会报错!
2、整数比较符
比较符 |
描述 |
实例 |
-eq, equal |
等于 |
[ 1 -eq 1 ] 为true |
-ne, not equal |
不等于 |
[ 1 -ne 1 ] 为false |
-gt, greate than |
大于 |
[ 1 -gt 1 ] 为false |
-lt, lesser than |
小于 |
[ 1 -lt 1 ] 为false |
-ge, greate or equal |
大于或者等于 |
[ 1 -ge 1 ] 为true |
-le, lesser or equal |
小于或者等于 |
[ 1 -le 1 ] 为true |
3、字符串比较符
运算符 |
描述 |
实例 |
== |
等于 |
[ "a" == "a" ] 为true |
!= |
不等于 |
[ "a" != "a" ] 为false |
-n |
字符串长度不等于 0 为真 |
VAR1=1;VAR2="" [ -n "$VAR1" ]为 true [ -n "$VAR2" ]为 false |
-z |
字符串长度等于0为真 |
VAR1=1;VAR2="" [ -z "$VAR1" ]为false [ -z "$VAR2" ]为 true |
注意:使用-n 判断字符串长度时,变量要加双引号,养成好习惯,字符串比较时都加上双引号。
4、文件测试
测试符 |
描述 |
实例 |
-e |
文件或者目录存在为真 |
[ -e path ] path 存在为 true |
-f |
文件存在为真 |
[ -f file_path ] 文件存在为 true |
-d |
目录存在为真 |
[ -d dir_path ] 目录存在为 true |
-r |
有读权限为真 |
[ -r file_path ]file_path有读权限为真 |
-w |
有写权限为真 |
[ -w file_path ]file_path有写权限为真 |
-x |
有执行权限为真 |
[ -x file_path ]file_path有执行权限为真 |
5、布尔运算符
预算符 |
描述 |
实例 |
! |
非关系,条件结果取反 |
[ ! 1 -eq 2 ]为true |
-a |
和关系,在[]表达式中使用 |
[ 1 -eq 1 -a 2 -eq 2 ]为true两者都为真才为真 |
-o |
或关系,在[]表达式中使用 |
[ 1 -eq 1 -o 2 -eq 1 ]为true两者有一真则为真 |
6、逻辑判断符
判断符 |
描述 |
实例 |
&& |
逻辑与,在[[]]表达式中 或判断表达式是否为真时使用 |
[[ 1 -eq 1 && 2 -eq 2 ]]为 true [ 1 -eq 1 ] && echo 'true',如果&&前面的表达式为true则执行后面的 |
|| |
逻辑或,在[[]]表达式中 或判断表达式是否为真时使用 |
[[ 1 -eq 1 || 2 -eq 1 ]]为 true [ 1 -eq 2 ] || echo 'true',如果||前面的 表达式为false则执行后面的 |
注意:[] 不支持以上两个逻辑判断符,应该使用布尔运算符
7、整数运算
运算符/表达式 |
描述/实例 |
+ |
加法 |
- |
减法 |
* |
乘法 |
/ |
除法 |
% |
取余 |
$(( )) |
$((1+1)) |
$[ ] |
$[ ] |
8、其它运算工具
命令 |
描述 |
实例 |
let |
赋值并运算,支持++、-- |
let VAR=(1+2)*3 ; echo $VAR x=10 ; y=5 let x++;echo $x 每执行一次 x 加 1 let y--;echo $y 每执行一次 y 减 1 let x+=2 每执行一次 x 加 2 let x-=2 每执行一次 x 减 2 |
expr |
乘法*需要加反斜杠转义\* |
expr 1 \* 2 运算符两边必须有空格 expr \( 1 + 2 \) \* 2 使用双括号时要转义 |
bc |
计算器,支持浮点运算、平方等 |
bc 本身就是一个计算器,可直接输入命令,进入解释器 echo 1 + 2 |bc 将管道符前面标准输出作为 bc 的标准输入 echo "1.2+2" |bc scale #小数点后保留多少位,默认是0位 echo “scale=2;4/3” |bc |
9、ell括号用途总结
( ) |
用途1:在运算中,先计算小括号里面的内容 用途2:数组 用途3:匹配分组 |
(( )) |
用途1:表达式,不支持-eq这类的运算符。不支持-a和-o,支持<=、>=、<、>这类比较符和&&、|| 用途2:C语言风格的for(( ))表达式 |
$( ) |
执行Shell命令,与反引号` `等效 |
$(( )) |
用途1:简单算数运算 用途2:支持三目运算符 $(( 表达式?数字:数字 )) |
[ ] |
条件表达式,里面不支持逻辑判断符 |
[[ ]] |
条件表达式,里面不支持-a和-o,不支持<=和>=比较符,支持-eq、<、>这类比较符。支持=~模式匹配,也可以不用双引号也不会影响愿意,比 [ ] 更加通用 |
$[ ] |
简单算数运算 |
{ } |
对逗号(,)和点点(…)起作用,比如touch {1,2}创建1和2文件,touch {1…3}创建1、2、和3文件 |
${ } |
用途1:引用变量 用途2:字符串处理 |
整数比较:
-eq 等于 if [ "$a" -eq "$b" ]
-ne 不等于 if [ "$a" -ne "$b" ]
-gt 大于 if [ "$a" -gt "$b" ]
-ge 大于等于 if [ "$a" -ge "$b" ]
-lt 小于 if [ "$a" -lt "$b" ]
-le 小于等于 if [ "$a" -le "$b" ]
< 小于(需要双括号) (( "$a" < "$b" ))
<= 小于等于(...) (( "$a" <= "$b" ))
> 大于(...) (( "$a" > "$b" ))
>= 大于等于(...) (( "$a" >= "$b" ))
字符串比较:
= 等于 if [ "$a" = "$b" ]
== 与=等价
!= 不等于 if [ "$a" = "$b" ]
< 小于,在ASCII字母中的顺序:
if [[ "$a" < "$b" ]]
if [ "$a" \< "$b" ] #需要对<进行转义
> 大于
-z 字符串为null,即长度为0
-n 字符串不为null,即长度
shell基础之变量及表达式的更多相关文章
- Shell基础-环境变量配置文件
Shell基础-环境变量配置文件 source 配置文件 或者 . 配置文件: 把环境变量写入配置文件后,需要用户重新登陆才能生效,而是用source命令,则能直接生效 主要的配置文件: /etc/p ...
- shell基础、变量、相关脚本
目录 一.shell基础 书写规范 引号 配置文件 read交互 脚本调式 小节总结 二.变量 变量类型 位置变量 状态变量 替换和删除 变量补充 变量运算 小节总结 三.相关脚本面试题 统计hist ...
- shell基础及变量
一 Shell概述 1.Shell的作用——命令解释器,“翻译官” shell作为一个人机接口,用于解释用户输入的命令,将命令解释为Linux内核可以执行的2进制代码,并将执行的结果返回在标准终端上. ...
- centos shell基础 alias 变量单引号 双引号 history 错误重定向 2>&1 jobs 环境变量 .bash_history source配置文件 nohup & 后台运行 cut,sort,wc ,uniq ,tee ,tr ,split, paste cat> 2.txt <<EOF 通配符 glob模式 发邮件命令mail 2015-4-8 第十二节课
centos shell基础知识 alias 变量单引号 双引号 history 错误重定向 2>&1 jobs 环境变量 .bash_history source配置文件 ...
- Linux Shell基础篇——变量
一.Shell中的变量 注:这里所说的Shell是Bash Shell,我姑且统称为Shell. Shell中的变量分为用户自定义变量.环境变量.位置参数变量.预定义变量.在Shell中,变量的默认类 ...
- shell基础及变量符号
kernel主要的功能: 1.内存的管理 2.设备驱动程序 3.文件系统的管理 4.进程的管理 5.网络系统 vim /etc/profile.d/ profile(主配置文件) .d(子配置文件 ...
- Shell基础之四 变量与运算
shell变量与运算 变量存在于内存中.假设变量str,设置或修改变量属性时,不带$号,只有引用变量的值时才使用$号.也就是说在内存中,标记变量的变量名称是str,而不是$str. 变量数据的存储方式 ...
- linux笔记:shell基础-bash变量
shell变量设置规则: 变量的分类: 环境变量的设置: 系统常见环境变量: 位置参数变量(用来接收脚本的参数): 预定义变量: 接收键盘输入(将键盘输入的值赋值给变量名): 用declare声明变量 ...
- Shell基础:变量类型 & 运算符
Shell变量 Shell支持三种类型的变量 用户自定义变量:用户自定义的变量,变量名以英文字母或下划线开头,区分大小写. 位置变量:根据位置传递参数给脚本的变量,默认支持9个位置变量 $1,$2,$ ...
随机推荐
- Dynamics CRM9.0安装CRM的时候提示Microsoft.Crm.Setup.Server.RegisterSandboxServiceAction操作失败
如图: 这种问题有两种情况会遇到.第一种是一个域装多套CRM产品会提示这个问题这个问题是解决不了的. 还一种情况就是安装9.0及以后的产品先安装了ADFS再安装产品就会提示这个错误. 第二种解决办法就 ...
- Dynamics Crm Plugin插件注册的问题及解决方案(持续更新。。。。。。)
1.注册插件的时候回遇到如下提示 Plug-in assembly does not contain the required types or assembly content cannot be ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(二)——通讯框架讲解
首先感谢张队@geffzhang公众号转发了上一篇文章,希望广大.neter多多推广dapr,让云原生更快更好的在.net这片土地上落地生根. 目录:一.通过Dapr实现一个简单的基于.net的微服务 ...
- 吃透什么是KVM虚拟化
概念: 云计算自从提出,一直没有一个明确而统一的定义.维基百科对云计算做了如下的描述:云计算是一种通过因特网以服务的方式提供动态可伸缩的虚拟化的资源的计算模式.美国国家标准与技术研究院( NIST)定 ...
- dubbo负载均衡策略和集群容错策略都有哪些?动态代理策略呢?
(1)dubbo负载均衡策略 1)random loadbalance 默认情况下,dubbo是random load balance随机调用实现负载均衡,可以对provider不同实例设置不同的权重 ...
- Vue入门学习
目录 Vue 简介 第一个Vue程序 Vue基本语法 双向绑定 组件 Axios异步通信 计算属性 Slot 自定义事件 第一个Vue-cli程序 webpack学习使用 Vue-Router路由 v ...
- 额!Java中用户线程和守护线程区别这么大?
在 Java 语言中线程分为两类:用户线程和守护线程,而二者之间的区别却鲜有人知,所以本文磊哥带你来看二者之间的区别,以及守护线程需要注意的一些事项. 1.默认用户线程 Java 语言中无论是线程还是 ...
- 030- 控制语句if…else…
语法: 第一种结构: if(boolean表达式){ java语句; } 解释:如果if后面的boolean表达式是true就执行大括号里面的java语句 如果是false就不执行大括号中的java语 ...
- hdu4807枚举费用流
题意: 给你一个有向图,每条边上都有每一时刻的最大流量,有k个人在点0,他们要去点n-1,问你最晚到达的那个人最快要多久. 思路: 这个题目做了很多次,用过费用流,也用过最大流,结 ...
- 【转】在CentOS 8 / RHEL 8上配置主/从BIND DNS服务器
转自: https://zh.codepre.com/centos-2700.html 前言 本指南描述了在CentOS 8 / RHEL 8 Linux上配置BIND DNS服务器所需的步骤.在Ce ...