shell基础

Shell

一、 Shell基础

1. 概述

	Shell 是一个用C语言编写的程序,它是用户使用Linux的桥梁。Shell既是一种命令语言,也是一种程序设计语言。
	用户通过 Shell 提供的界面访问操作系统内核的服务。
	Shell 是一种解释型语言。这种语言经过编写后不经过任何编译就可以执行,是一种脚本语言。和编译型语言是执行前翻译不同,解释型语言的程序是执行时翻译,所以效率要差一 些。 

2. Shell种类

cat /etc/shells
	/bin/sh
	/bin/bash
	/usr/bin/sh
	/usr/bin/bash
	/usr/bin/fish
	/usr/local/bin/fishlogin

3. Shell工作模式

3.1 互动模式
3.2 脚本模式
vim helloWorld.sh
# 写入以下内容
#!/bin/bash
# 是一个标记,告诉系统执行这个文件需要的解释器
# this line is a comment “#”号开头的行代表注释
echo "Hello World"

# 脚本运行
bash helloWorld.sh
# “.”号和source命令也都可以执行脚本,且不需要可执行权限
. helloWorld.sh
# source在当前bash环境下读取并执行FileName中的命令
source helloWorld.sh
# 给脚本添加可执行权限,然后直接就可以执行了
chmod o+x helloWorld.sh
./helloWorld.sh

4. 变量

	变量就是其值可以变化的量。从变量的本质来说,变量名是指向一片用于存储数据的内存空间。变量分为变量有局部变量、环境变量(全局变量)。在脚本中,往往需要使用变量来存储有用信息,比如文件名、路径名、数值等,通过这些变量可以控制脚本的运行行为。
4.1 局部变量
	是指在某个shell中生效的变量,对其他shell来说无效,局部变量的作用域被限定在声明它们的shell中,可以使用local内建命令来“显式”的声明局部变量,但仅限于函数内使用。
4.2 环境变量
	环境变量通常又称“全局变量”,以区别于局部变量。在shell脚本中,变量默认就是全局的,为了让子shell继承当前shell的变量,可以使用export命令将其定义为环境变量。
4.3 bash默认预设环境变量
  • bash中默认包含有几十个预设的环境变量。下面介绍一些常用的:

    # BASH: Bash shell的全路径
    echo $BASH
    # BASH_VERSION : bash shell的版本
    echo $BASH_VERSION
    # EUID:记录当前用户的UID
    echo $EUID
    # FUNCNAME:在用户函数体内部,记录当前函数体的函数名。
    vim funcname.sh
    # 写入以下内容
    #!/bin/bash
    funcname() {
    echo $FUNCNAME
    }
    
    # 运行
    . funcname.sh
    
    # HISTCMD:记录下一条命令在history命令中的编号
    # HISTFILE:记录history命令记录文件的位置
    # HISTFILESIZE:设置HISTFILE文件记录命令的行数
    # HISTSIZE:设置命令缓冲区的大小
    # HOSTNAME:设置主机名
    # HOSTTYPE:展示主机的架构
    # MACHTYPE:主机类型的GNU标识,这种标识有统一的结构。一般来说是“主机架构-公司-系统-gnu”
    # LANG:设置当前系统的语言环境
    # PWD:记录当前目录
    # OLDPWD:记录之前目录
    # PATH:代表命令的搜索路径,非常重要
    
4.4 变量名
	shell中的变量必须以字母或者下划线开头,后面可以跟数字、字母和下划线,长度没有限制,区分大小写。
4.5 变量赋值和取值
# 变量赋值
# 注意点1:变量名和变量值之间用等号紧紧相连,之间没有任何空格
name=john
# 注意点2:当变量值中有空格时必须用引号括起,否则会出现错误,可以是双引号,也可以是单引号
name="li si"

# 变量取值
echo $name
# 严谨的方法是${}
echo ${name}

# 取消变量 unset后面也是可以跟上函数名来取消函数
unset name
4.6 特殊变量
  1. 位置参数

    • $0:代表脚本本身名字

    • $1----$9:第一个位置参数-------第9个位置参数

    • $#:脚本参数的个数总和

    • $@:表示脚本的所有参数

    • $* :表示脚本的所有参数

      vim posion.sh
      # 写入以下内容
      #!/bin/bash
      echo "这个脚本的名字是:$0"
      echo "参数一共有$#"
      echo "参数的列表是: $@"
      echo "参数的列表是: $*"
      echo "第一个参数是: $1"
      echo "第二个参数是: $2"
      echo "第三个参数是:$3"
      
      # 调用测试
      . posion.sh a b c
      
  2. 脚本或者命令返回值:$?

    • 正常退出的命令和脚本应该返回值为0,任何非0的返回值都表示命令未正确退出或未正常执行。

      ifcofj
      echo $?
      ping -c 1 www.baidu.com
      echo $?
      

5. 数组

  • 概述

    	数组是一种特殊的数据结构,其中的每一项被称为一个元素,对于每个元素,都可以用索引的方式取出元素的值。使用数组的典型场景是一次性要记录很多类型相同的数据时(但不一定必须要相同)。比如,为了记录班级中所有人的数学成绩,如果不用数据来处理,那就只能定义所有人成绩的变量。shell中的数组对元素个数没有限制,但只支持一维数组。
    
  • 使用

    # 使用declare [dɪˈkler] (公布; 宣布; 宣告; 表明)命令定义数组Array
    # declare [+/-][rxi][变量名称=设置值] 或 declare -f
    # +/-  "-"可用来指定变量的属性,"+"则是取消变量所设的属性。
    # -f  仅显示函数。
    # -a  将变量var声明为数组变量。
    # r  将变量设置为只读。
    # x  指定的变量会成为环境变量,可供shell以外的程序来使用。
    # i  [设置值]可以是数值,字符串或运算式。
    declare -a Array
    Array[0]=0
    Array[1]=1
    Array[2]="HelloWorld"
    
    # 也可以在创建的同时赋值
    declare -a Name=('john' 'sue')
    Name[2]='wang'
    
    # 更简单的方式来创建数组
    Name=('john' 'sue')
    
    # 还可以跳号赋值
    Score=([3]=3 [5]=5 [7]=)
    
    
    
    
    # 数组操作
    
    # 数组取值:格式为:${数组名[索引]}
    echo ${Array[0]}
    echo ${Array[2]}
    echo ${Name[1]}
    # 一次性取出数组所有的值
    # 得到的是以空格隔开的元素值
    echo ${Array[@]}
    # 输出的是一整个字符串
    echo ${Array[*]}
    
    # 数组长度:即数组元素个数
    # 利用“@”或“*”字符,可以将数组扩展成列表,然后使用“#”来获取数组元素的个数。
    echo ${#Array[*]}
    echo ${#Array[@]}
    
    # 数组截取 可以截取某个元素的一部分,对象可以是整个数组或某个元素。
    # 取出数组的第一个、第二个元素
    echo ${Array[@]:1:2}
    # 取出第二个元素从第0个字符开始连续5个字符
    echo ${Array[2]:0:5}
    
    # 连接数组:将若干个数组进行拼接操作
    Conn=(${Array[@]} ${Name[@]})
    echo ${Conn[@]}
    
    # 替换元素:将数组内某个元素的值替换成其他值
    Array=(${Array[@]/HelloWorld/HelloJohn})
    echo ${Array[@]}
    
    # 取消数组或元素:使用unset命令
    unset Array[1]
    echo ${Array[@]}
    unset Array
    echo ${Array[@]}
    
5.1 只读变量
  • 只读变量又称常量,通过readonly内建命令创建,创建时需要赋值,并且之后无法修改。

    readonly RO=100
    RO=200
    

6. 转义和引用

6.1 转义
  • shell中有很多特殊字符,会有特殊意义,但是有时候会造成麻烦,需要转义才可以使用,转义符号为“\”

    echo 8 \* 8 =64
    echo \$Dollar
    
6.2 引用
  • 引用是指将字符串用某种符号括起来,以防止特殊字符被解析为其他意思。

  • shell中一共有4种引用符,分别为双引号、单引号、反引号和转义符。

  • 双引号可以引用除$符号、反引号、转义符之外的所有字符;单引号可以引用所有字符;反引号则会将反引号中的内容解释为系统命令

    echo "current directory is $PWD"
    echo 'current directory is $PWD'
    
    # 命令替换:是指将命令的标准输出作为值赋给某个变量。
    # 格式有反引号和$(),建议使用$()
    TIME=`date +%F`
    echo $TIME
    TIME2=$(date +%F)
    echo $TIME2
    

7. 运算符

7.1 概述
	shell中的运算符主要有比较运算符(用于整数比较)、字符串运算符(用于字符串测试)、文件操作运算符(用于文件测试)、逻辑运算符、算术运算符、位运算符、自增自减运算符等。
7.2 算数运算符
  • 概述

    	算术运算符指的是加、减、乘、除、余、幂等常见的算术运算,以及加等、减等、乘等、除等、余等复合算术运算。要特别注意的是,shell只支持整数计算,也就是说所有可能产生小数的运算都会舍去小数部分。
    
  • 使用

    # Bash shell 的算术运算有四种方式:
    # 1:使用 expr 外部程式 注意! '4' '+' '5' 这三者之间要有空白
    r=`expr 4 + 5`
    echo $r
    r=`expr 4 \* 5`
    echo $r
    
    # 2:使用 $(( ))
    r=$(( 4 + 5 ))
    echo $r
    
    # 3:使用 $[ ]
    r=$[ 4 + 5 ]
    echo $r
    
    # 乘法
    r=$(( 4 * 5 ))
    r=$[ 4 * 5 ]
    echo $r
    # 除法
    r=`expr 40 / 5`
    r=$(( 40 / 5 ))
    r=$[ 40 / 5 ]
    echo $r
    # 减法
    r=`expr 40 - 5`
    r=$(( 40 - 5 ))
    r=$[ 40 - 5 ]
    echo $r
    # 求余数
    r=$[ 100 % 43 ]
    echo $r
    # 乘幂 (如 2 的 3 次方)
    r=$(( 2 ** 3 ))
    r=$[ 2 ** 3 ]
    echo $r
    
    # !! expr 沒有乘幂 !!
    
    # 4:使用 let 命令
    # 加法:
    n=10
    let n=n+1
    echo $n
    # 乘法:
    let m=n*10
    echo $m
    # 除法:
    let r=m/10
    echo $r
    # 求余数:
    let r=m%7
    echo $r
    # 乘冪:
    let r=m**2
    echo $r
    
    # !! 虽然Bash shell 有四种算术运算方法,但并不是每一种都是跨平台的,建议使用expr。 !!
    
    # 另外,我们在 script 中经常有加1操作,以下四法皆可:
    m=$[ m + 1]
    m=`expr $m + 1`
    m=$(($m + 1))
    let m=m+1
    
7.3 位运算符
  • 位运算符是基于内存中二进制数据的运算,也就是基于位的运算。

    # 位运算的左移、右移元素其实就是整数在内存中的“左右移动”。其中左移运算符为<<,右移运算符为>>。
    let "a=4<<2"
    echo $a
    
    let "b=4>>2"
    echo $b
    
    # 按位与运算(&),也就是取小,只有对应的二进制值都为1的时候,结果才为1
    let "c=192&255"
    echo $c
    
    # 按位或运算(|),是将两个整数写成二进制的形式,然后同位置相比较,只要对应的位 置有1,结果就是1。
    let "d=8|4"
    echo $d
    
    # 按位异或运算(^),是将两个整数写成二进制的形式,然后同位置比较,只要相同,结果为0,否则为1。
    let "e=10^3"
    echo $e
    
7.4 自增自减
  • 概述

    	增自减运算主要包括前置自增、前置自减、后置自增、后置自减等。前置自增或 自减操作会首先修改变量的值,然后再将变量的值传递出去;后置自增或后置自减则会首先 将变量的值传递出去,然后再修改变量的值。自增符号为“++”,自减符号为“--”,操作 对象只能是变量,不能是常数或表达式。
    
  • 使用

    Add_01=10
    Add_02=10
    # 前置自增
    let Add_03=(++Add_01)
    echo $Add_03
    echo $Add_01
    
    #后置自增
    let Add_04=(Add_02++)
    echo $Add_04
    echo $Add_02
    

8. 特殊字符

8.1 通配符
	通配符用于模式匹配,常见的通配符有\*、?和用[]括起来的字符序列。
	\*:代表任意长度的字符串。例如:a\*可以匹配以a开头的任意长度的字符串,但是不包括点号和斜线号。也就是说a\*不能匹配abc.txt
	?:用于匹配任一单个字符。
	\[ ]: 代表匹配其中的任意一个字符,比如[abc]代表匹配a或则b或则c,[ ]中可以用“-”表明起止,比如[a-c]等同于[abc]。\*和?在\[ ]中则变成了普通字符,没有通配的功效。 
8.2 引号:包括单引号和双引号
	双引号中的字符除了“$”、“\”、反引号依然保留其特殊用途外,其余字符都作为普通字符处理。 单引号中的字符都作为普通字符处理 。
8.3 注释符
	"#"代表注释,除了”#!“,其表示某个解释器的路径,且必须在整个脚本的第一行。 
8.4 大括号
  • 变量扩展。引用变量,例如变量VAR,可以使用${VAR}引用。
echo {x1,x2,x3}{y1,y2,y3}
echo file{1..6}
echo file{4,8,9}
8.5 控制字符
	控制字符即ctrl+key组合键一起使用,用于修改终端或文本显示。控制字符是交互式使用的,不能用于脚本中。 
8.6 感叹号
	通常代表逻辑反,例如 != 表示不等于。

9. 重定向

9.1 概述
	计算机最基础的功能是可以提供输入输出操作。对于Linux系统来说,通常以键盘为默 认输入设备,又称标准输入设备;以显示器为默认的输出设备,又称标准输出设备。所谓重 定向,就是将原本应该从标准输入设备(键盘)输入的数据,改由其他文件或设备输入,或 将原本应该输出到标准输出设备(显示器)的内容,改由输出到其他文件或设备上。  
9.2 文件标识符
 	文件标识符是重定向中很重要的一个概念,Linux使用0到9的整数指明了与特定进程相 关的数据流,系统在启动一个进程的同时会为该进程打开三个文件:标准输入(stdin)、 标准输出(stdout)、标准错误输出(stderr),分别用文件标识符0、1、2来标识。如果 要为进程打开其他的输入输出,则需要从整数3开始标识。默认情况下,标准输入为键盘, 标准输出和错误输出为显示器。 std = standard [ˈstændərd] (标准)
 	
 	ll /dev/stdin
	ll /dev/stdout
	ll /dev/stderr
9.3 I/O重定向符号和用法
  • I/O重定向可以将任何文件、命令、脚本、程序的输出重定向到另外一个文件、命令、程序或脚本。

    # 显示当前目录文件 test.sh test1.sh test1.sh实际不存在
    touch test.sh
    ls test.sh test1.sh
    
    # 输出重定向
    
    # 把正确输出写入suc.txt 自动创建suc.txt
    ls test.sh test1.sh > suc.txt
    cat suc.txt
    
    # 把错误输出,不输出到屏幕,输出到err.txt
    ls test.sh test1.sh > suc.txt 2> err.txt
    
    # 继续追加把输出写入suc.txt err.txt “>>”追加操作符
    ls test.sh test1.sh >> suc.txt 2>> err.txt
    
    # 将错误输出信息关闭掉
    # &[n] 代表是已经存在的文件描述符,&1 代表输出 &2代表错误输出 &-代表关闭与它绑定的描述符
    # Linux系统将所有设备都当作文件来处理,而Linux用文件描述符来标识每个文件对象。
    # 内核(kernel)利用文件描述符(file descriptor)来访问文件。文件描述符是非负整数。
    # 打开现存文件或新建文件时,内核会返回一个文件描述符。读写文件也需要使用文件描述符来指定待读写的文件。
    ls test.sh test1.sh 2>&-
    # 将错误输出信息输出到黑洞
    ls test.sh test1.sh 2>/dev/null
    
    # 关闭所有输出
    # 关闭 1 ,2 文件描述符
    ls test.sh test1.sh 1>&- 2>&-
    # 将1,2 输出转发给/dev/null设备
    ls test.sh test1.sh 1>/dev/null 2>/dev/null
    # 将错误输出2 绑定给 正确输出 1,然后将 正确输出 发送给 /dev/null设备 这种常用
    # !!1>/dev/null 2>&1顺序很重要!!
    ls test.sh test1.sh 1>/dev/null 2>&1
    ls test.sh test1.sh &>/dev/null
    
    # PS: 默认控制输出重定向为1 可以省略不写。
    # 例: ls test.sh test1.sh 1>/dev/null 2>&1 等价于 ls test.sh test1.sh >/dev/null 2>&1
    
    
    # 输入重定向
    # EOF 通常与 << 结合使用,<<EOF 表示后续的输入作为子命令或子shell的输入,直到遇到 EOF
    
    cat > a.txt << EOF
    > hello world
    > EOF
    cat a.txt
    
9.4 管道符 |
	管道表现为输入输出重定向的一种方法,可以将一个命令的输出内容当做下一个命令的输入内容,可以通过多个简单命令的共同协作来完成较为复杂的工作。
	
	ll /etc | less

二、 测试和判断

1. 测试结构

1.1 文件测试
1.test expression
2.[ expression ]

# expression为表达式

1.2 字符串测试

  • shell中的字符串比较主要有等于、不等于、大于、小于、是否为空等测试。

    -n  string      若string的长度不为0,则为真,否则为假
    -z  string      若string的长度为0,则为真,否则为假
    string1 = string2    若string1等于string2,则为真,否则为假
    string1 != string2   若string1不等于string2,则为真,否则为假
    string1 > string2    若string1排在string2之前则为真,否则为假
    string1 < strint2    若string1排在string2之后则为真,否则为假
    

1.3 整数比较

  • 整数测试是一种简单的算术运算,作用在于比较两个整数的大小关系,测试成立则返回

    -eq	等于
    -gt	大于
    -lt	小于
    -ge	大于等于
    -le	小于等于
    -ne	不等于
    

1.4 逻辑测试符

  • 逻辑测试用于连接多个测试条件,并返回整个表达式的值。

  • 逻辑测试主要有逻辑非、逻辑与、逻辑或3种

    # 非(!)、与(-a)、或(-o)
    
    ! expression	如果expression为真,则测试结果为假
    expressionl -a expression2		expressionl和expression2同时为真,则测试结果为真
    expression1 -O expression2		expressionl和expression2只要有一-个为真,则测试结果为真
    
  • 实例

    # 逻辑非
    [root@bzx ~]# [ ! -e /var/log/messages ]
    [root@bzx ~]# echo $?
    1
    
    # 逻辑与
    [root@sunday-test ~]# [ -e /var/log/messages -a -e /var/log/messages01 ]
    [root@sunday-test ~]# echo $?
    1
    
    # 逻辑或
    [root@sunday-test ~]# [ -e /var/log/messages -o -e /var/log/messages01 ]
    [root@sunday-test ~]# echo $?
    0
    
  • shell中的逻辑运算符,也有逻辑非、逻辑与、逻辑或 3种

    !		逻辑非,对真假取反.
    &&		逻辑与,连接两个表达式,只有两个表达式为真结果才为真
    ||		逻辑或,连接两个表达式,只要有一个表达式为真结果就为真
    

三、判断语句

1. If语句

# if判断结构
if expression; then 
	command 
fi

# if/else判断结构
if expression; then 
	command 
else 
	command 
fi

# if/elif/else判断结构
if expression1;then 
	command1 
elif expression2; then 
	command2 
elif expression3 ; then 
	command3 
... 
fi

2. case语句

# case判断结构
case VAR in 
var1) command1 ;; 
var2) command2 ;; 
var3) command3 ;; 
... 
*) command4 ;; 
esac
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值