本节内容

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 变量的命名规范和大部分编程语言都一样:

  • 变量名由数字、字母、下划线组成;
  • 必须以字母或者下划线开头;
  • 不能使用 Shell 里的关键字(通过 help 命令可以查看保留关键字)。

变量定义举例:

url=http://www.baidu.com
time_15_age=18
real_name='ken' _author="ken"

使用变量

使用一个定义过的变量,只要在变量名前面加美元符号$即可,如:

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 | 随机生成一个 0 至 32767 的整数 |
| $HOSTNAME | 主机名 |

1.4.2 普通变量与临时环境变量

普通变量定义: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@ken ~]# bash test name age
File Name: test
First Parameter : name
First Parameter : age
Quoted Values: name age
Quoted Values: name age
Total Number of Parameters : 2

退出状态

$? 可以获取上一个命令的退出状态。所谓退出状态,就是上一个命令执行后的返回结果。

退出状态是一个数字,一般情况下,大部分命令执行成功会返回 0,失败返回 1。

不过,也有一些命令返回其他值,表示不同类型的错误。

[root@ken ~]# echo ken
ken
[root@ken ~]# echo $?
0
[root@ken ~]# systemctl restart jj
Failed to restart jj.service: Unit not found.
[root@ken ~]# echo $?
5

条件表达式

|                              表达式 |                实例 |

|                         [ expression ] |                 [ 1 -eq 1 ] |

|                        [[ expression ]] |                [[ 1 -eq 1 ]] |

|                        test  expression |            test 1 -eq 1 ,等同于[] |

[root@ken ~]# [ 1 -eq 2 ] && echo "this is true" || echo "this is false"

this is false

[root@ken ~]# [ 1 -eq 1 ] && echo "this is true" || echo "this is false"

this is true

注意:括号中的表达式前后都有空格,否则会报错!

条件判断

[]

[ 1 -eq 1 ]

1.条件表达式的括号里面前后都要有空格

例子1:

[root@ken ~]# [ 1 -eq 1 ] && echo “1” || echo “2”

1

例子2:

[root@ken ~]# [ 1 -eq 1 ] && echo “1” || echo “2” || echo “3”

1

[root@ken ~]# [ 1 -eq 1 ] && echo “1” || echo “2” && echo “3”

1

3

例子3:

[root@ken ~]# [ 1 -lt 1 ] && echo “1” || echo “2”

2

注释:

&&: 表示的含义是前面的命令执行成功,&&后面的命令才会执行

||:表示的含义是前面的命令执行失败,||后面的命令才会执行

例子1: eq

[root@ken ~]# [ 1 -eq 1 ] && echo 1 || echo 2

1

例子2:ne

[root@ken ~]# [ 1 -ne 1 ] && echo 1 || echo 2

2

例子3:le

[root@ken ~]# [ 1 -le 1 ] && echo 1 || echo 2

1

例子4:ge

[root@ken ~]# [ 1 -ge 1 ] && echo 1 || echo 2

1

例子5:lt

[root@ken ~]# [ 1 -lt 1 ] && echo 1 || echo 2

2

例子6:gt

[root@ken ~]# [ 1 -gt 1 ] && echo 1 || echo 2

2

字符串比较符

== : 判断两个字符串是否相等

!=: 判断两个字符串不相等

-n: 判断字符串是否不为空

-z: 判断字符串是否为空

注意:在判断字符串的时候一定要加上双引号!

例子1:==

[root@ken ~]# name=ken

[root@ken ~]# [ “$name” == “ken” ] && echo 1 || echo 2

1

例子2:!=

[root@ken ~]# [ “$name” != “ken” ] && echo 1 || echo 2

2

例子3:-n

[root@ken ~]# [ -n “$name” ] && echo 1 || echo 2

1

例子4:-z

[root@ken ~]# [ -z “$name” ] && echo 1 || echo 2

2

文件测试

-e: exist 存在即为真 #可以判断目录和文件

-f: 存在且为普通文件

-d: 存在且为目录

例子1:-e

[root@ken ~]# [ -e /etc/passwd ] && echo 1 || echo 2

1

[root@ken ~]# [ -e /etc/passwdd ] && echo 1 || echo 2

2

[root@ken ~]# [ -e /etc ] && echo 1 || echo 2

1

[root@ken ~]# [ -e /etcd ] && echo 1 || echo 2

2

例子2:-f

[root@ken ~]# [ -f /etc/passwd ] && echo 1 || echo 2

1

[root@ken ~]# [ -f /etc/passwdd ] && echo 1 || echo 2

2

[root@ken ~]# [ -f /etc ] && echo 1 || echo 2

2

例子3:-d

[root@ken ~]# [ -d /etc ] && echo 1 || echo 2

1

[root@ken ~]# [ -d /etc/passwd ] && echo 1 || echo 2

2

[root@ken ~]# [ -d /etc/passwddd ] && echo 1 || echo 2

2

布尔运算符

!: 取反

-a: && 和

-o:|| 或

布尔运算符通常用在[]

例子1:!

[root@ken ~]# [ ! 1 -eq 1 ] && echo 1 || echo 2

2

例子2:-a

[root@ken ~]# [ 1 -eq 1 -a 2 -lt 2 ] && echo 1 || echo 2

2

-a:

条件一: 条件二 合

true true true

true false false

false true false

false false false

例子3:-o

[root@ken ~]# [ 1 -eq 1 -o 2 -lt 2 ] && echo 1 || echo 2

1

[root@ken ~]# [ 1 -eq 2 -o 2 -lt 2 ] && echo 1 || echo 2

2

-o:

条件一: 条件二 合

true true true

true false true

false true true

false false false

逻辑判断符

第一种用法:

[root@ken ~]# [[ 1 -eq 1 && 2 -eq 2 ]] && echo 1 || echo 2

1

第二种用法:

[root@ken ~]# [ 1 -eq 1 ] && [ 2 -eq 2 ^C&& echo 1 || echo 2

&&: 前面的命令执行成功就会执行后面的命令

||: 前面的命令执行失败就会执行后面的命令

整数运算

例子1:*

[root@ken ~]# num=$((2*4))

[root@ken ~]# echo $num

8

例子2:+

[root@ken ~]# num1=$((2+4))

[root@ken ~]# echo $num1

6

例子3:-

[root@ken ~]# num2=$((num1-4))

[root@ken ~]# echo $num2

2

例子4:/

[root@ken ~]# num3=$((num2/2))

[root@ken ~]# echo $num3

1

例子5:%

[root@ken ~]# num4=$((5%2))

[root@ken ~]# echo $num4

1

例子6:**

[root@ken ~]# num5=$((5**2))

[root@ken ~]# echo $num5

25

例子7:

[root@ken ~]# num6=$((3/2))

[root@ken ~]# echo $num6

1

整数运算 — let

自加一

写法一:推荐写法

[root@ken ~]# num=1

[root@ken ~]# let num++

[root@ken ~]# echo $num

2

写法二:

[root@ken ~]# let num+=1

[root@ken ~]# echo $num

3

写法三:

[root@ken ~]# let num=num+1

[root@ken ~]# echo $num

4

自减–》上同

例子2:

[root@ken ~]# let num+=2

[root@ken ~]# echo $num

6

例子1:

[root@ken ~]# bc

bc 1.06.95

Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.

This is free software with ABSOLUTELY NO WARRANTY.

For details type `warranty’.

1+1

2

3*6

18

例子2:

[root@ken ~]# echo “1+1” | bc

2

shell括号用途总结

Shell编程、part2的更多相关文章

  1. Linux学习笔记(17) Shell编程之基础

    1. 正则表达式 (1) 正则表达式用来在文件中匹配符合条件的字符串,正则是包含匹配.grep.awk.sed等命令可以支持正则表达式:通配符用来匹配符合条件的文件名,通配符是完全匹配.ls.find ...

  2. shell编程:定义简单标准命令集

    shell是用户操作接口的意思,操作系统运行起来后都会给用户提供一个操作界面,这个界面就叫shell,用户可以通过shell来调用操作系统内部的复杂实现,而shell编程就是在shell层次上进行编程 ...

  3. Linux Shell编程入门

    从程序员的角度来看, Shell本身是一种用C语言编写的程序,从用户的角度来看,Shell是用户与Linux操作系统沟通的桥梁.用户既可以输入命令执行,又可以利用 Shell脚本编程,完成更加复杂的操 ...

  4. Shell编程菜鸟基础入门笔记

    Shell编程基础入门     1.shell格式:例 shell脚本开发习惯 1.指定解释器 #!/bin/bash 2.脚本开头加版权等信息如:#DATE:时间,#author(作者)#mail: ...

  5. Linux_10------Linux之shell编程------变量

    .-9 vim num.sh #! /bin/bash num1=$1 num2=$2 sum=$(($num1+$num2)) #变量sum是num1和num2的综合 echo $sum 执行 ./ ...

  6. 需要交互的shell编程——EOF(转载)

    在shell编程中,”EOF“通常与”<<“结合使用,“<<EOF“表示后续的输入作为子命令或子shell的输入,直到遇到”EOF“, 再次返回到主调shell,可将其理解为分 ...

  7. ****CodeIgniter使用cli模式运行,把php作为shell编程

    shell简介 在计算机科学中,Shell俗称壳(用来区别于核).而我们常说的shell简单理解就是一个命令行界面,它使得用户能与操作系统的内核进行交互操作. 常见的shell环境有:MS-DOS.B ...

  8. Shell 编程基础之变量和环境变量

    一.变量赋值和引用 Shell 编程中,使用变量无需事先声明,同时变量的命名不惜遵循如下规则: 首个字符必须为字母(a-z,A-Z)或者_ 变量名中间不能有空格,可以使用_连接 不能使用其他表达符号 ...

  9. Linux Shell编程基础

    在学习Linux BASH Shell编程的过程中,发现由于不经常用,所以很多东西很容易忘记,所以写篇文章来记录一下 ls   显示当前路径下的文件,常用的有 -l 显示长格式  -a 显示所有包括隐 ...

  10. centos 下建用户 shell编程

    useradd 用户名 passwd 用户名 cat /etc/passwd  查看用户信息 删除用户 userdel -r   加一个 -r 表示把用户及用户的主目录都删除 su  切换用户 sud ...

随机推荐

  1. loj2589 「NOIP2009」Hankson 的趣味题

    对于质因数分解理解还不到位. 此题可知$lcm$是$x$的倍数,$x$是$lcm$的约数,只要在$lcm$的分解质因数里对每一个质因子讨论种数即可. 具体来说,对于$lcm$的一个质因子$p$,讨论$ ...

  2. Linux内核编译完整过程

    Linux内核编译完整过程 通过网上的资料我自己的实际内核编译,我把对Linux内核编译的过程写在这里,也许对其他的Linux爱好者的编译学习有些帮助,其中很大部分是网上的资料,另外就是我在实际编译过 ...

  3. MongoDB学习笔记之文档

    #向集合中插入文档有两种方式(insert.save) db.col.insert({title: 'MongoDB 教程', description: 'MongoDB 是一个 Nosql 数据库' ...

  4. 第二篇【Zabbix客户端的完整布署】

    关于Zabbix服务端布署请查看 1.上传zabbix安装包(源码包默认(Server和Agent是一起的)) [root@sms-v2 ~]# ll /root/ -rw-r--r-- root r ...

  5. [RCTF]Pwn200 wp

    0x00: XCTF开赛了,只看了pwn,这次还比较有意思,有x86  x64  arm mips 多种cpu构架的pwn.自己只搞出了pwn200 0x01: 基本信息: x64 动态链接 有调试符 ...

  6. Windows Server 快速生成免费SSL证书 (letsencrypt)

    最近官网需求部署个SSL证书,一番操作后把借鉴的网站与实际过程记录下来 Let's Encrypt,官网是https://letsencrypt.org/,它是一个由各大公司赞助的公益组织: 有趋势有 ...

  7. javascript中的原型和原型链(二)

    原型(prototype) 函数的 prototype 属性(图) 每个函数都有一个prototype属性,它默认指向一个Object空对象(即称为:原型对象) 原型对象中有一个属性construct ...

  8. MessagePack Java 0.6.X 快速开始指南 - 安装

    0.6.x 版本的 MessagePack 已经过期被淘汰了.如果你现在开始使用 MessagePack 话,请不要使用这个版本. 我们再这里保留 0.6.x 版本的内容主要用于参考用途. 最新的 M ...

  9. protoc 编译工具

    在进行开发 protoc 之前,你需要首先在你的计算机中安装 protoc 编译工具. 下载编译工具 进入 Protocol Buffers 的源代码中然后选择发布的版本中,找到对应的版本.项目的链接 ...

  10. hdu 3572 仪器与任务 最大流 好题 体会建图思想

    Task Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...