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 在默认情况下不会区分变量类型,即使你将整数和小数赋值给变量,它们也会被视为字符串,这一点和大部分的编程语言不同。

【二】.变量

  1.定义变量

  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='feige'
_author="feige"

使用变量:

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

author="feige"

echo $author

echo ${author}

变量名外面的花括号{ }是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:

skill="Java"

echo "I am good at ${skill}Script"

如果不给 skill 变量加花括号,写成echo "I am good at $skillScript",解释器就会把$skillScript当成一个变量(其值为空),代码执行结果就不是我们期望的样子了。

推荐给所有变量加上花括号{ },这是个良好的编程习惯。

2.系统变量

在命令行提示符直接执行 env、set 查看系统或环境变量。env 显示用户环境变量,set 显示 Shell 预先定义好的变量以及用户变量。可以通过 export 导出成用户变量。

一些写 Shell 脚本时常用的系统变量:

$SHELL

默认 Shell

$HOME

当前用户家目录

$IFS

内部字段分隔符

$LANG

默认语言

$PATH

默认可执行程序路径

$PWD

当前目录

$UID

当前用户 ID

$USER

当前用户

$HISTSIZE

历史命令大小,可通过 HISTTIMEFORMAT 变量设置命令执行时间

$RANDOM

随机生成一个 0 至 32767 的整数

$HOSTNAME

主机名

3. 普通变量与临时环境变量

普通变量定义: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}

第二次对变量赋值时不能在变量名前加$,只有在使用变量时才能加$。

4.单引号和双引号的区别

前面我们还留下一个疑问,定义变量时,变量的值可以由单引号' '包围,也可以由双引号" "包围,它们到底有什么区别呢?不妨以下面的代码为例来说明:

#!/bin/bash

url="http://c.biancheng.net"

website1='C语言中文网:${url}'

website2="C语言中文网:${url}"

echo $website1

echo $website2

运行结果:

C语言中文网:${url}

C语言中文网:http://c.biancheng.net

1单引号' '包围变量的值时,单引号里面是什么就输出什么,即使内容中有变量和命令(命令需要反引起来)也会把它们原样输出。这种方式比较适合定义显示纯字符串的情况,即不希望解析变量、命令等的场景。

2以双引号" "包围变量的值时,输出时会先解析里面的变量和命令,而不是把双引号中的变量名和命令原样输出。这种方式比较适合字符串中附带有变量和命令并且想将其解析后再输出的变量定义

【建议】:如果变量的内容是数字,那么可以不加引号;如果真的需要原样输出就加单引号;其他没有特别要求的字符串等最好都加上双引号,定义变量时加双引号是最常见的使用场景。

5.将命令的结果赋值给变量

Shell 也支持将命令的执行结果赋值给变量,常见的有以下两种方式:

variable=`command`

variable=$(command)

第一种方式把命令用反引号包围起来,反引号和单引号非常相似,容易产生混淆,所以不推荐使用这种方式;第二种方式把命令用$()包围起来,区分更加明显,所以推荐使用这种方式。

例如,我创建了一个名为test的文本文件。下面的代码中,使用cat命令将文本的内容读取出来,并赋值给一个变量,然后使用echo命令输出。

——# echo "this is great" >test

——# mes=`cat test`

——# echo $mes

this is great

6.删除变量

使用 unset 命令可以删除变量。

语法:

unset variable_name

变量被删除后不能再次使用;unset 命令不能删除只读变量。

举个例子:

[root@feige ~]# name=feige

[root@feige ~]# echo $name

feige

[root@feige ~]# unset name

[root@feige ~]# echo $name

[root@feige ~]#

上面没有任何输出。

定义只读变量

——# name=feige

——# readonly name

——# echo $name

feige

——# unset name

-bash: unset: name: 无法反设定: 只读 variable

7.变量类型

运行shell时,会同时存在三种变量:

1) 局部变量

局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。

2) 环境变量

所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。

3) shell变量

shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行

8.特殊变量列表(shell变量)

$0  当前脚本的文件名

$n  传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。

$#  传递给脚本或函数的参数个数。

$*  传递给脚本或函数的所有参数。

$?  上个命令的退出状态,或函数的返回值。

$$  当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。

请看下面的脚本:

#!/bin/bash

echo "文件名: $0"

echo "第一个参数 : $1"

echo "第二个参数 : $2"

echo "所有参数: $*"

echo "参数个数 : $#"

运行结果:

[root@feige ~]# bash test name age

文件名: test

第一个参数 : name

第二个参数 : age

所有参数: name age

参数个数 : 2

退出状态

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

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

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

——# echo feige

feige

——# echo $?

0

——# systemctl restart jj

Failed to restart jj.service: Unit not found.

——# echo $?

5

【三】.表达式

1.条件表达式

表达式

实例

[ expression ]

[ 1 -eq 1 ]

[[ expression ]]

[[ 1 -eq 1 ]]

test  expression

test 1 -eq 1 ,等同于[]

——# [ 1 -eq 2 ] && echo "this is true" || echo "this is false"

this is false

——# [ 1 -eq 1 ] && 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 判断字符串长度时,变量要加双引号,养成好习惯,字符串比较时都加上双引号。

# [ -z $a ] && echo yes || echo no

yes

# [ -n $a ] && echo yes || echo no

yes

# 加了双引号才能正常判断是否为空

# [ -z "$a" ] && echo yes || echo no

yes

# [ -n "$a" ] && echo yes || echo no

no

4.文件测试

测试符

描述

实例

-e

文件或者目录存在为真

[ -e path ] path 存在为 true

-f

文件存在为真

[ -f file_path ] 文件存在为 true

-d

目录存在为真

[ -d dir_path ] 目录存在为 true

-r

有读权限为真

[ -r file_path ]file_path有读权限为真

-w

有写权限为真

[ -r file_path ]file_path有写权限为真

-x

有执行权限为真

[ -r 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

9.shell括号用途总结

==================================分割线=======================================

末学者笔记--shell编程上 2 玄的更多相关文章

  1. 末学者笔记--shell编程上 1 玄

    Shell 编程 [内容简列]: 1.shell简介 2. shell分类 3. 查看shell 4. 第一个shell脚本 5. shell编程常用命令 5.1 grep 5.2 cut 5.3 s ...

  2. Linux_(3)Shell编程(上)

    一.shell 简介Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁.Shell 既是一种命令语言,又是一种程序设计语言.Shell 是指一种应用程序,这个应用程序提供了一个 ...

  3. sed命令详解 vim高级技巧 shell编程上

    第1章 sed命令详解 1.1 查找固定的某一行 1.1.1 awk命令方法 [root@znix ~]# awk '!/oldboy/' person.txt 102,zhangyao,CTO 10 ...

  4. 速查笔记(Linux Shell编程<上>)

    转载自: http://www.cnblogs.com/stephen-liu74/archive/2011/11/01/2202027.html 零.shell中的内部变量: 1.    $?:   ...

  5. shell编程上

    1.1  前言 1.1.1  为什么学Shell Shell脚本语言是实现Linux/UNIX系统管理及自动化运维所必备的重要工具, Linux/UNIX系统的底层及基础应用软件的核心大都涉及Shel ...

  6. Shell编程笔记

    Shell编程笔记与Windows下熟悉的批处理类似,也可以将一些重复性的命令操作写成一个脚本方便处理.   修改别人的脚本,运行后遇到个问题 setenv: command not found 查证 ...

  7. shell编程学习笔记(十):Shell中的for循环

    shell编程中可以实现for循环遍历 先来写一个最简单的吧,循环输出从1到10,脚本内容为: #! /bin/sh for i in {1..10} do echo $i done 上面的代码从1到 ...

  8. shell编程学习笔记【原创】

    本文为本人学习笔记,如有转载请注明出处,谢谢 一.Bourne Shell 有如下四种变量: 用户自定义变量 位置变量,即命令行参数 预定义变量 环境变量 二.位置变量 $ 与键入的命令行一样,包含脚 ...

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

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

随机推荐

  1. BZOJ 2733 永无乡

    splay启发式合并 启发式合并其实就是把集合数量小的合并到集合数量大的里去. 怎么合并呢,直接一个一个插入就行了.. 用并查集维护连通性,find(i)可以找到所在splay的编号 这题好像还可以合 ...

  2. 【BZOJ4001】[TJOI2015]概率论(生成函数)

    [BZOJ4001][TJOI2015]概率论(生成函数) 题面 BZOJ 洛谷 题解 这题好仙啊.... 设\(g_n\)表示\(n\)个点的二叉树个数,\(f_n\)表示\(n\)个点的二叉树的叶 ...

  3. Java编程思想_笔记_第二章_一切都是对象

    第二章对于知识只是点到,会在以后章节会详细展开. 笔记的侧重会偏向记录自己知识模糊的地方.比如 xxx 很重要很难很实用,但是已经熟练使用就没有记录,而 “使用对象.成员名称来使用成员变量”,较简单而 ...

  4. 【简】题解 AWSL090429 【市场】

    因为这有个时间的限制 并且  求的时间都是前缀和 那么 我们可以根据时间将排序 因为题中没有修改可以直接用背包预处理出答案 但是因为题目ci mi<=1e9   vi<=300 所以发现不 ...

  5. 三、TensorFlow模型的保存和加载

    1.模型的保存: import tensorflow as tf v1 = tf.Variable(1.0,dtype=tf.float32) v2 = tf.Variable(2.0,dtype=t ...

  6. Thrax-构建基于语法的语言模型工具

    安装 http://www.openfst.org/twiki/bin/view/GRM/ThraxQuickTour http://cslu.ogi.edu/~sproatr/Courses/Tex ...

  7. LOJ #6485 LJJ 学二项式定理

    QwQ LOJ #6485 题意 求题面中那个算式 题解 墙上暴利 设$ f(x)=(sx+1)^n$ 假设求出了生成函数$ f$的各项系数显然可以算出答案 因为模$ 4$的缘故只要对于每个余数算出次 ...

  8. Excel如何快速统计一列中相同数值出现的个数--数据透视表

    excel如何快速统计一列中相同数值出现的个数_百度经验 --这里介绍了两种解决方式,用第一种https://jingyan.baidu.com/article/9113f81b2c16822b321 ...

  9. python捕获异常及方法总结

    调试Python程序时,经常会报出一些异常,异常的原因一方面可能是写程序时由于疏忽或者考虑不全造成了错误,这时就需要根据异常Traceback到出错点,进行分析改正:另一方面,有些异常是不可避免的,但 ...

  10. git本机服务器配置(四):git+TortoiseGit+gitblit配置本机服务器

    1.配置本机git服务器 1.1 打开gitblit服务器,登录之前设置的服务页面localhost:1081 1.2.登录账号,账号在(三)中有提到. 1.3 打开用户中心 1.4 点击SSH Ke ...