Shell基础知识及字符处理

1.1 简介

Shell是一个C语言编写的脚本语言,它是用户与Linux的桥梁,用户输入命令交给Shell处理,Shell将相应的操作传递给内核(Kernel),内核把处理的结果输出给用户。
下面是处理流程示意图:

wKioL1hLhIqDimSkAACW4Y1j1qE949.png

Shell既然是工作在Linux内核之上,那我们也有必要知道下Linux相关知识。
Linux是一套免费试用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。
1983年9月27日,Richard Stallman(理查德-马修-斯托曼)发起GNU计划,它的目标是创建一套完全自由的操作系统。为保证GNU软件可以自由的使用、复制、修改和发布,所有的GNU软件都有一份在禁止其他人添加任何限制的情况下授权所有权利给任何人的协议条款,GNU通用公共许可证(GNU General Plubic License,GPL),说白了就是不能做商业用途。
GNU是"GNU is Not Unix"的递归缩写。UNIX是一种广泛使用的商业操作系统的名称。
1085年,Richard Stallman又创立了自由软件基金会(Free Software Foundation,FSF)来为GNU计划提供技术、法律以及财政支持。
1990年,GNU计划开发主要项目有Emacs(文本编辑器)、GCC(GUN Compiler Collection,GNU编译器集合)、Bash等,GCC是一套GNU开发的编程语言编译器。还有开发一些UNIX系统的程序库和工具。
1991年,Linuxs Torvalds(林纳斯- 托瓦兹)开发出了与UNIX兼容的Linux操作系统内核并在GPL条款下发布。
1992年,Linux与其他GUN软件结合,完全自由的GUN/Linux操作系统正式诞生,简称Linux。
1995年1月,Bob Young创办ACC公司,以GNU/Linux为核心,开发出了RedHat Linux商业版。
Linux基本思想有两点:第一,一切都是文件;第二,每个软件都有确定的用途。与Unix思想十分相近。
1.2 Shell基本分两大类
1.2.1 图形界面Shell(GUI Shell)
GUI为Unix或者类Unix操作系统构造一个功能完善、操作简单以及界面友好的桌面环境。
主流桌面环境有KDE,Gnome等。
1.2.2 命令行界面Shell(CLI Shell)
CLI是在用户提示符下键入可执行指令的界面,用户通过键盘输入指令,完成一系列操作。
在Linux系统上主流的CLI实现是Bash,是许多Linux发行版默认的Shell。还有许多Unix上用的Shell,例如tcsh、csh、ash、bsh、ksh等等。
1.3 第一个Shell脚本
本教程主要讲解在大多Linux发行版下默认Bash Shell。Linux系统是RedHat下的CentOS操作系统,完全免费。与其商业版RHEL(Red Hat Enterprise Linux)出自同样的源代码,不同的是CentOS并不包含封闭源代码软件和售后支持。
用vi打开test.sh,编写:
# vi test.sh
#!/bin/bash
echo "Hello world!"
第一行设置运行环境,第二行打印Hello world!
写好后,开始执行,执行Shell脚本有三种方法:
方法1:直接用bash解释器执行
# bash test.sh
Hello world!
方法2:添加可执行权限
# ll test.sh
-rw-r--r--. 1 root root 32 Aug 18 01:07 test.sh
# chmod +x test.sh
# ./test.sh       
-bash: ./test.sh: Permission denied
# chmod +x test.sh
# ./test.sh # ./在当前目录
Hello world!
方法3:source命令执行,以当前默认Shell执行
# source test.sh
Hello world!
1.4 Shell变量
1.4.1 系统变量
在命令行提示符直接执行env、set查看系统或环境变量。env显示用户环境变量,set显示Shell预先定义好的变量以及用户变量。可以通过export导出成用户变量。
一些写Shell脚本时常用的系统变量:
$SHELL     默认Shell
$HOME     当前用户家目录
$IFS     默认内部域分隔符
$LANG     默认语言
$PATH     默认可执行程序路径
$PWD     当前目录
$UID     用户ID
$USER     当前用户
$HISTSIZE     历史命令大小,可通过HISTTIMEFORMAT变量设置命令执行时间
1.4.2 普通变量与临时环境变量
普通变量定义:VAR=value
临时环境变量定义:export VAR=value
变量引用:$VAR
下面看下他们之间区别:
Shell进程的环境变量作用域是Shell进程,当export导入到系统变量时,则作用域是Shell进程及其Shell子进程。

wKiom1h5u9-hDgKPAACXubaoIwc055.png

wKioL1h5u-zje5LnAAAVtzVGMAg690.png

ps axjf输出的第一列是PPID(父进程ID),第二列是PID(子进程ID)

当SSH连接Shell时,当前终端PPID(-bash)是sshd守护程序的PID(root@pts/0),因此在当前终端下的所有进程的PPID都是-bash的PID,比如执行命令、运行脚本。

所以当在-bash下设置的变量,只在-bash进程下有效,而-bash下的子进程bash是无效的,当export后才有效。

进一步说明:再重新连接SSH,去除上面定义的变量测试下

wKiom1h5u_jCzVOgAADnS47Zjfc308.png

所以在当前shell定义的变量一定要export,否则在写脚本时,会引用不到。
还需要注意的是退出终端后,所有用户定义的变量都会清除。
在/etc/profile下定义的变量就是这个原理,后面有章节会讲解Linux常用变量文件。
1.4.3 位置变量
位置变量指的是函数或脚本后跟的第n个参数。
$1-$n,需要注意的是从第10个开始要用花括号调用,例如${10}
shift可对位置变量控制,例如:
#!/bin/bash
echo "1: $1"
shift
echo "2: $2"
shift
echo "3: $3"
# bash test.sh a b c
1: a
2: c
3:
每执行一次shift命令,位置变量个数就会减一,而变量值则提前一位。shift n,可设置向前移动n位。
1.4.4 特殊变量
$0    脚本自身名字
$?    返回上一条命令是否执行成功,0为执行成功,非0则为执行失败
$#    位置参数总数
$*    所有的位置参数被看做一个字符串
$@    每个位置参数被看做独立的字符串
$$    当前进程PID
1.5 变量引用
1.5.1 自定义变量与引用
# VAR=123
# echo $VAR
123
Shell中所有变量引用使用$符,后跟变量名。
有时个别特殊字符会影响正常引用,那么需要使用${VAR},例如:
# VAR=123
# echo $VAR
123
# echo $VAR_   # Shell允许VAR_为变量名,所以此引用认为这是一个有效的变量名,故此返回空
# echo ${VAR}
123
还有时候变量名与其他字符串紧碍着,也会误认为是整个变量:
# echo $VAR456
# echo ${VAR}456
123456
1.5.2 将命令结果作为变量值
# VAR=`echo 123`
# echo $VAR
123
# VAR=$(echo 123)
# echo $VAR
123
这里的反撇号等效于$(),都是用于执行Shell命令。
1.6 双引号和单引号
在变量赋值时,如果值有空格,Shell会把空格后面的字符串解释为命令:
# VAR=1 2 3
-bash: 2: command not found
# VAR="1 2 3"
# echo $VAR
1 2 3
# VAR='1 2 3'
# echo $VAR
1 2 3
看不出什么区别,再举个说明:
# N=3
# VAR="1 2 $N"
# echo $VAR
1 2 3
# VAR='1 2 $N'
# echo $VAR
1 2 $N
单引号是告诉Shell忽略特殊字符,而双引号则解释特殊符号原有的意义,比如$、!。
1.7 注释
Shell注释也很简单,只要在每行前面加个#号,即表示Shell忽略解释。

2.1 获取字符串长度

1

2

3

4

5

# VAR='hello world!'

# echo $VAR

hello world!

# echo ${#VAR}

12

2.2 字符串切片

 

格式:

${parameter:offset}

${parameter:offset:length}

截取从offset个字符开始,向后length个字符。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

截取hello字符串:

# VAR='hello world!'

# echo ${VAR:0:5}

hello

截取wo字符:

# echo ${VAR:6:2}

wo

截取world!字符串:

# echo ${VAR:5}

world!

截取最后一个字符:

# echo ${VAR:(-1)}

!

截取最后二个字符:

# echo ${VAR:(-2)}

d!

截取从倒数第3个字符后的2个字符:

# echo ${VAR:(-3):2}

ld

2.3 替换字符串

格式:${parameter/pattern/string}

1

2

3

4

5

6

7

# VAR='hello world world!'

将第一个world字符串替换为WORLD:

# echo ${VAR/world/WORLD}

hello WORLD world!

将全部world字符串替换为WORLD:

# echo ${VAR//world/WORLD}

hello WORLD WORLD!

2.4 字符串截取

 

格式:

${parameter#word}   # 删除匹配前缀

${parameter##word}  

${parameter%word}   # 删除匹配后缀

${parameter%%word}

# 去掉左边,最短匹配模式,##最长匹配模式。

% 去掉右边,最短匹配模式,%%最长匹配模式。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

# URL="http://www.baidu.com/baike/user.html"

//为分隔符截取右边字符串:

# echo ${URL#*//}         

www.baidu.com/baike/user.html

以/为分隔符截取右边字符串:

# echo ${URL##*/}

user.html

//为分隔符截取左边字符串:

# echo ${URL%%//*}     

http:

以/为分隔符截取左边字符串:

# echo ${URL%/*}

http://www.baidu.com/baike

以.为分隔符截取左边:

# echo ${URL%.*}

http://www.baidu.com/baike/user

以.为分隔符截取右边:

# echo ${URL##*.}

html

# 去掉左边,从左边匹配第一个,##从右边匹配第一个。

% 去掉右边,从右边匹配第一个,%%从左边匹配第一个。

有*号情况下才这样。

2.5 变量状态赋值

 

${VAR:-string}  如果VAR变量为空则返回string

${VAR:+string}  如果VAR变量不为空则返回string

${VAR:=string}  如果VAR变量为空则重新赋值VAR变量值为string

${VAR:?string}  如果VAR变量为空则将string输出到stderr

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

如果变量为空就返回hello world!:

# VAR=

# echo ${VAR:-'hello world!'}

hello world!

如果变量不为空就返回hello world!:

# VAR="hello"

# echo ${VAR:+'hello world!'}

hello world!

如果变量为空就重新赋值:

# VAR=

# echo ${VAR:=hello}

hello

# echo $VAR

hello

如果变量为空就将信息输出stderr:

# VAR=

# echo ${VAR:?value is null}   

-bash: VAR: value is null

${}主要用途大概就这么多了,另外还可以获取数组元素,在后面章节会讲到。

 

 

博客地址:http://lizhenliang.blog.51cto.com

QQ群:Shell/Python运维开发群 323779636

 

 

2.6 字符串颜色

再介绍下字符串输出颜色,有时候关键地方需要醒目,颜色是最好的方式:

字体颜色

字体背景颜色

显示方式

30:黑

31:红

32:绿

33:黄

34:蓝色

35:紫色

36:深绿

37:白色

40:黑

41:深红

42:绿

43:黄色

44:蓝色

45:紫色

46:深绿

47:白色

0:终端默认设置

1:高亮显示

4:下划线

5:闪烁

7:反白显示

8:隐藏

格式:

\033[1;31;40m  # 1是显示方式,可选。31是字体颜色。40m是字体背景颜色。

\033[0m     # 恢复终端默认颜色,即取消颜色设置。

示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

#!/bin/bash

# 字体颜色

for in {31..37}; do

    echo -e "\033[$i;40mHello world!\033[0m"

done

# 背景颜色

for in {41..47}; do

    echo -e "\033[47;${i}mHello world!\033[0m"

done

# 显示方式

for in {1..8}; do

    echo -e "\033[$i;31;40mHello world!\033[0m"

done

wKioL1hOEA3hOXTKAAA5ci8LYEk174.png-wh_50

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值