linux shell 脚本-基础知识(一)

linux shell 脚本的编写是Linux程序员最基本也是必须学会的技能。
这里主要介绍学习shell脚本的基本基础。

命令解释器

    #指定命令解释器
    #! /bin/bash
    ...

命令解释器:shell脚本中第1行的 #! /bin/bash 告诉当前shell应该调用哪个shell来执行当前的程序。

shell脚本中的注释风格

  • 单行注释:在前面加一个"#"
#注释1
#注释2
#注释3
  • 多行注释:使用冒号":"配合here document 使用
:<<BLOCK

....注释内容

BLOCK

变量和引用

变量的命名

shell 中,变量名可以由字母、数字或者下划线组成,并且只能以字母或者下划线开头。

变量的类型

根据变量类型确定的时间,可以将程序设计语言分为两类,分别是静态类型语言和动态类型语言。
静态类型语言:在程序的编译期间就确定变量类型的语言,例如JAVA、C++ 和PASCAL
动态类型语言:在程序执行过程中才确定变量的数据类型的语言,如VBScript、PHP、Python。
shell是一种动态类型语言和弱类型语言。
在shell中,变量的数据类型无需显示地声明,变量地数据类型会根据不同的操作有所变化。
准确地讲,shell中的变量是不分数据类型的,统一地按照字符串存储。
例子1:变量的数据类型

#!/bin/bash

#定义变量下x,并且赋值为123
x=123
#变量x加1
let "x += 1"
#输出变量x的值
echo "x = $x"

#替换x中的1为abc,并且将值赋给变量y
y=${x/1/abc}
#输出变量y的值
echo "y = $y"
#声明变量y(整型变量)
declare -i y
#输出变量y的值
echo "y = $y"
#变量y的值加1
let "y += 1"
#输出变量y的值
echo "y = $y"

输出为:

x = 124
y = abc24
y = abc24
y = 1

为了执行加法运算,shell会自动进行数据类型的转换,如果遇到含有非数字的字符串,则该字符串将被转换成整数0。

shell变量的定义

在shell中,通常情况下用户可以直接使用变量,无需先进行定义。
当用户第一次使用某个变量名时,实际上就同时定义了这个变量,在变量的作用域内,用户都可以使用该变量。
例2: 直接使用变量定义变量

#! /bin/bash
  
#定义变量a
a=1
#定义变量b
b="hello"
# 定义变量c
c="hello world"

通过以上方式可以非常方便地定义变量,但是,对于变量的某些属性却不容易控制,例如,变量的类型和读写属性等。为了更好地控制变量地相关属性,bash提供了一个名称为 declare 的命令来声明变量,该命令的基本语法如下:


    declare attribute variable

其中,attributeattributeattribute表示变量的属性,常用属性如下:

  • -p:显示所有变量的值
  • -i:将变量定义为整数。在之后就可以直接对表达式求值,结果只能是整数。如果求值失败或者不是整数,就设置为0
  • -r:将变量声明为只读变量。但这没有必要。所有变量都不必显示定义就可以用做数组
  • -f:显示所有自定义函数,包括名称和函数体
  • -x:将变量设置成环境变量,这样在随后的脚本和程序中可以使用

参数variable表示变量名称。
例3:使用不同的方法声明变量

#! /bin/bash
  
#定义变量x,并将一个算术式赋给它
x=6/3
echo "$x"
#定义变量x为整数
declare -i x
echo "$x"
#将算术式赋给变量x
x=6/3
echo "$x"
#将字符串赋给变量x
x=hello
echo "$x"
#将浮点数赋给变量x
x=3.14
echo "$x"
#取消变量x的整数属性
declare +i x

#重新将算术式赋给变量x
x=6/3
echo "$x"
#求表达式的值
x=$[6/3]
echo "$x"
#求表达式的值
x=$((6/3))
echo "$x"
#声明只读变量x
declare -r x
echo "$x"
#尝试为只读变量赋值
x=5
echo "$x"

结果为:

6/3
6/3
2
0
declare_data.sh: line 16: 3.14: syntax error: invalid arithmetic operator (error token is ".14")
0
6/3
2
2
2
declare_data.sh: line 35: x: readonly variable

因为bash并不内置对浮点数的支持,所以得到了上图结果中的第一个错误;第二个错误是因为加了只读权限,尝试修改便会报错。

引号

在shell编程中,正确理解引号的作用非常重要。
shell语言中一共有三种引号,分别为单引号(’’)、双引号("")和反引号(``)。这3种引号的作用是不同的:

  • 单引号括起来的字符都作为普通字符出现;
  • 由双引号括起来的字符,除“$”、“\”、“’”和“"”这几个字符仍是特殊字符并保留其特殊功能外,其余字符仍作为普通字符对待;
  • 由反引号括起来的字串被shell解释为命令,在执行时,shell首先执行该命令,并以它的标准输出结果取代整个反引号部分。

变量的作用域

全局变量

在shell语言中,全局变量是使用范围较大的变量,它不仅限于某个局部使用。全局变量可以在脚本中定义,也可以在某个函数中定义。

在脚本中定义的变量都是全局变量,其作用域为从被定义的地方开始,一直到shell脚本结束或者被显示的删除。

所以在函数内部定义的默认情况下也是全局变量,其作用域为从函数被调用时执行变量的定义的地方开始,一直到shell脚本结束或者被显示地删除为止

例4: 全局变量

#! /bin/bash
  
#定义函数
func() 
{
    echo "$v1"
    #修改变量的值
    v1=200
}
#在脚本中定义全局变量x
v1=100
#调用函数
func
echo "$v1"

局部变量

在shell中,通过关键字 local 定义局部变量,同时,上述提到的函数参数也是局部变量。
例5:使用local关键字定义局部变量

#! /bin/bash
func()
{
    #使用local关键字定义局部变量
    local v2=200
}   
#调用函数
func
echo "$v2"

结果为空:


由于使用了local来定义v2变量,所以在函数外部就访问不到v2的值,因此得到一个空值。
如果用户在函数外面定义了一个全局变量,同时在某个函数内部定义又存在相同名称的局部变量,而在调用该函数时,函数内部的局部变量会屏蔽函数外部定义的全局变量。也就是说,在出现同名的情况下,函数内部的局部变量会优先被使用。

系统变量

shell语言的系统变量主要在对参数判断和命令返回值判断时使用,包括脚本和函数的参数,以及脚本和函数的返回值。
shell语言中的系统变量并不多,但是十分有用,特别是在做一些参数检测的时候。

变量名 含义
$n 表示传递给脚本的第n个参数, $1表示第1个参数,$2表示第二个参数…
$# 脚本的参数个数
$@ 以”参数1“ ”参数2“ ”参数3“…的形式返回参数的值
$* 以”参数1 参数2 参数3…“的形式返回所有参数的值
$0 此脚本的名字
$? 上一条命令的返回值
$$ 返回本进程的进程ID

例6:使用系统变量

#! /bin/bash    
    
#输出脚本参数的个数    
echo "the number of parameters is $#"    
#输出上一个命令的状态码    
echo "the return code of last command is $?"    
#输出脚本名称    
echo "the script name is $0"    
#输出所有的参数    
echo "the parameters are $*"    
#输出其中的几个参数    
#注意:此处不能写成$11,不然会被误认为是$1变量加上一                                     
echo "\$1=$1; \$2=$2; \$11=${11}"    

结果:

rootVM_16_3_centos base]$ ./param.sh a b c d e f g h i j k l m n 
the number of parameters is 14
the return code of last command is 0
the script name is ./param.sh
the parameters are a b c d e f g h i j k l m n
$1=a; $2=b; $11=k

变量的赋值和清空

一个没有初始化的shellshellshell变量被认为是一个空字符串。用户可以通过变量的赋值操作来完成变量的声明并赋予一个特定的值。并且可以通过赋值语句为一个变量多次赋值,以改变其值。

在shell中,变量的赋值可以用如下语法:

variable_name=value

其中,variable_ name表示变量名,value表示将要赋给变量的值。
一般情况下,shell中将所有普通变量的值都看做字符串。如果value中包含空格、制表符和换行符,则必须用单引号或者双引号将其引起来。双引号中允许变量替换,而单引号中则不允许

中间的"="称为赋值符号,赋值符号的左右两边不能直接跟空格,否则shell会将其视为命令

通过在变量名前加上“$”来获取变量的值。

例7:引用shell变量

#! /bin/bash

v1=10
v2='RedHat Linux'
v3="RedHat Linux $HOSTTYPE"
v4=12345

#输出变量v1的值
echo "$v1"
#输出变量v2的值
echo "$v2"
#输出变量v3的值
echo "$v3"
#输出变量v4的值
echo "$v4"

# 字符串是可以直接连接在一起的
## 错误的写法
echo "$v4abc"
## 正确的写法
echo "${v4}abcd"

结果

10
RedHat Linux
RedHat Linux x86_64
12345

12345abcd

清除变量

不需要某个变量时,可以将其清除。当变量被清除后,其所代表的值也会消失。清除变量使用 unset 语句,其语法如下:

#! /bin/bash

v1="Hello world"
echo "$v1"
unset v1  #清除变量v1
echo "the value of v1 has been reset"
echo "clear$v1"

结果

Hello world
the value of v1 has been reset
clear

命令替换

所谓命令替换,是指在 shell 程序中,将某个 shell 的命令的执行结果赋给某个变量。在 bash 中,有两种语法可以进行命令替换,分别使用反引号和圆括号,如下

`shell_command`
$(shell_command)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,219评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,363评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,933评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,020评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,400评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,640评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,896评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,597评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,327评论 1 244
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,581评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,072评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,399评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,054评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,849评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,672评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,585评论 2 270

推荐阅读更多精彩内容

  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 4,310评论 0 5
  • 一、Python简介和环境搭建以及pip的安装 4课时实验课主要内容 【Python简介】: Python 是一个...
    _小老虎_阅读 5,618评论 0 10
  • 特别说明:以下内容来自简书,链接为原文出处,一切权益归原作者所有,在此感谢原作者的分享,大家可以点击以下链接查看原...
    沈祥佑阅读 535评论 0 4
  • 用了caffe有一段时间了,感觉自己写shell脚本的能力有待提高,特地从菜鸟笔记处系统的看了一遍,其实学习基础就...
    yichen_china阅读 1,807评论 2 30
  • 这篇文章是手册的中文译版整理而来(英文看着太慢了,感谢前人铺路Orz...),vim的markdown插件和实时预...
    Himryang阅读 6,842评论 0 20