shell脚本书写规范

shell脚本编程规范与书写习惯

1.开头加脚本解释器
2.附带作者及版权信息
3.脚本扩展名为  *.sh
4.脚本存放在固定的目录下
5.脚本尽量不使用中文
6.成对的符号 一次性书写完成
7.循环格式一次输入完成
8.中括号首尾要有一个空格

shell脚本的注释

# 后面的的内容一般为注释,可以使用vim 命令模式ctrl+v 可视化模块添加。也可以使用如下方法:
:<<EOF
需要注释的内容
EOF注:结尾的EOF必须从行首写,不能有空格, :冒号在shell中也是命令,表示深度不做。例如:
#!/bin/bash
echo "123"
:<<EOF
echo "234"
echo "345"
EOF

shell脚本的执行

1.当脚本每可执行权限或脚本开头文件没有指定解释器时推荐使用:
bash script_name
sh  script_name2.指定当前路径下执行脚本(脚本需要有执行权限)
chmod +x  script_name
再执行
/path/script_name
./script_name3.其他
cat script_name | sh
source script_name
sh < script_name
. script_name

父shell和子shell的概念

在A脚本运行b脚本,那么可以称b为A的子shell,A为父shell。
父shell和子shell之间是不能调用的,若需要调用变量需要使用source或 . 点。例如:
[root@m01 scripts]# cat 2.sh
#!/bin/bash
user=`whoami`
[root@m01 scripts]# sh 2.sh
[root@m01 scripts]# echo $user    [root@m01 scripts]# user=`whoami`
[root@m01 scripts]# echo $user
root
[root@m01 scripts]# unset user
[root@m01 scripts]# echo $user[root@m01 scripts]# # 使用source调用是可以读取到变量的
[root@m01 scripts]# source 2.sh
[root@m01 scripts]# echo $user
root总结:
使用source 和 .  点来执行脚本,相当于在shell下面执行脚本,变量互相可以调用。
bash和sh执行脚本,等于开启了一个新的shell,或者说开启了一个子shell,无法读取父定义的变量。

declare命令

声明变量,设置或显示变量的值和属性

例:
声明变量
[root@m01 scripts]# declare B=aaa
[root@m01 scripts]# echo $B
aaa

unset命令

删除指定shell变量或函数

参数:
-f  仅删除函数
-v  仅山粗变量(不包括只读变量)
-n  删除具有引用属性的变量名(如果该选项存在)案例:
[root@m01 scripts]# a=123
[root@m01 scripts]# echo $a
123
[root@m01 scripts]# unset a  #删除指定shell变量
[root@m01 scripts]# echo $a[root@m01 scripts]#

set命令

显示或设置特殊及shell变量。

set命令注意作用是显示系统中已经存在的shell变量,以及设置shell变量的新变量值。set命令不能定义新的shel变量,如有要定义新的变量可以使用declare命令以 “变量名=值” 的格式定义。参数:
-a 标示以修改的变量,以供输出值环境变量
-f 取消使用通配符
-n 只读指令,而不实际执行例:
[root@m01 scripts]# set |grep LANG
LANG=en_US.UTF-8

env命令

显示系统中已存在的环境变量

例:
过滤系统环境变量
[root@m01 scripts]# env |grep LANG
LANG=en_US.UTF-8

tee命令

从标注输入读取数据并重定向到标准输出和文件;要食醋胡的文件可以是一个或多个。

参数:
-a  追加到文件中而不是覆盖案例:
将信息通过管道符输出到标准输出并覆盖写入到文件中,加-a参数是追加而不是覆盖
[root@m01 scripts]# cat 2.sh | tee 2.txt
#!/bin/bash
user=`whoami`
[root@m01 scripts]# cat 2.txt
#!/bin/bash
user=`whoami`

readonly命令

标记shell变量或函数为只读

主要用途:
定义一个到多个变量并设置为只读属性
显示全部包含只读属性的变量/函数参数:
-a 指向数组
-A 指向关联数组
-f 指向函数
-p 显示全部只读变量
-- 在它之后的选项无效只读变量:是指不能被清除或重新赋值的变量。declare无法去除只读属性,unset不能删除只读变量。案例:
标记变量为只读变量
[root@m01 scripts]# A=XXX
[root@m01 scripts]# readonly A
[root@m01 scripts]# A=yyy
-bash: A: readonly variable
[root@m01 scripts]# unset A=yyy
-bash: unset: `A=yyy': not a valid identifier删除只读变量
cat << EOF| gdb
attach $$
call unbind_variable("变量名")
detach
EOF

变量知识

什么是变量

变量源自数学,是计算机语言中能存储计算结果或能表示值的抽象概念。

shell变量特性

默认情况下,在bash shell中是不会区分变量是什么类型的,如:常见的变量类型为整数,字符串,小数等。

shell变量分类

变量可以分为两类:
环境变量(全局变量):可以在创建他们的shell及其派生出来的任意子进程中使用,环境变量又可以分为自定义环境变量和bash内置环境变量。
普通变量(局部变量):只能在创建他们的shell函数或shell脚本中使用,普通变量一般由开发者在开发脚本程序是创建。

定义环境变量

如:PS1;PATH;HOME;UID等系统固有的,默认就表示一定的意义。系统级:/etc/profile   /etc/bashrc
用户级:~/.bash_profile  ~/.bashrc  ~/.bash_logout  ~/.bash_history设置环境变量有三种方法:
第一种:
export A=1
第二种:
B=2
export B
第三种:
declare -x C=3总结:
定义环境变量尽量大写;
使环境变量全局生效,可以写入/etc/profile文件中。
显示环境变量使用env和set命令
取消环境变量是 unset + 变量名1 变量名2  ...

定义永久变量

本地变量:用户私有变量,只有本用户可以使用,保存在家目录下的.bash_profile,.bashrc文件中
全局变量:所有用户都可以使用,保存在/etc/profile,/etc/bashrc文件中例如:
本地变量
[root@www ~]# tail -1 ~/.bash_profile
name='ccc'全局变量
[root@www ~]# tail -1 /etc/profile
export age=18

环境变量初始化与对于文件生效顺序

先加载/etc/profile;然后加载~/.bash_profile;再加载~/.bashrc;最后加载/etc/bashrc

普通变量(局部变量)

当前用户或脚本种生效,离开当前用户或脚本失效。

变量名:
规则:字母,数字,下划线,三种组合,以字母开头,中间不能有空格,不能使用数字开头。
要求:见名知意
驼峰语法:首个单词字母小写,其余单词首字母大写。
例如:
MyAge=18
my_age=18
myAge=18变量内容:
字符串:
变量名=value   #不加引号,解析变量或者命令,然后输出,出数字选择不加引号,value 值。
变量名='value' #加单引号,所见即所得
变量="value"   #加双引号,解析变量或命令,然后输出,字符串默认选择双引号,可以把要定义的内容作为一个整体。命令变量:
变量名=`ls`
变量名=$(ls)普通变量定义及输出小结:
变量名:
1)变量名定义要有一定的命令规范,并且要见名知意,推荐使用驼峰语法,myAge=18
2)变量名仅能使用字母,数字,下划线中的任意多个字符,并且尽量以字母开头变量内容:
在脚本中定义普通字符串变量,尽量把变量的内容用双引号括起来
单纯数字的变量内容可以不加引号
希望变量的内容原样输出加单引号
希望变量值引用命令并且获取命令结果使用反引号或$()赋值符号:
变量定义是赋值符号(=),赋值符号两端不要有空格变量输出:
使用或输出变量的内容可以使用$变量名,例:echo $变量名
若变量名后面有其他字符连接的时候,就必须给变量加上大括号{};例如:$db_t 就要改写成${db}_

特殊重要变量

特殊位置参数变量

符号 作用说明
$0 获取当前执行shell脚本的文件名,如果执行脚本带路径,那么就包括脚本路径
$n 获取当前执行的shell脚本的第n个参数值,n=1…9,当n为0时如上;如果n>9,则大括号括起来,如${10},这样才能代表第10个参数
$# 获取当前执行的shell脚本后面接的参数的总个数
$* 获取当前shell脚本所有传参的参数,不加引号同 @ ; 如 果 给 @;如果给 @;如果给*加上双引号,例如: "$*",则表示将所有的参数视为单个字符串,相当于"$1 $2 $3"
$@ 获取当前shell脚本所有传参的参数,不加引号同 ∗ , 如 果 给 * ,如果给 ∗,如果给@加上双引号,例如:"$@",则表示将所有的参数视为不同的独立字符串,相当于"$1" “$2” “ 3 " " . . . " , 这 是 将 多 参 数 传 递 给 其 他 程 序 的 最 佳 方 式 , 因 为 它 会 保 留 所 有 内 嵌 的 每 个 参 数 里 的 任 何 空 白 。 当 " 3" "...",这是将多参数传递给其他程序的最佳方式,因为它会保留所有内嵌的每个参数里的任何空白。当" 3""...",这是将多参数传递给其他程序的最佳方式,因为它会保留所有内嵌的每个参数里的任何空白。当"@“和”$*” 都加上双引号时,二者有区别,都不加双引号,二者无区别。
案例:
1. $0,输出当前执行脚本文件名,如果有路径则输出脚本路径[root@m01 scripts]# cat test.sh
#!/bin/bash
echo $0
[root@m01 scripts]# sh test.sh yyy
test.sh
[root@m01 scripts]# sh /scripts/test.sh
/scripts/test.sh2.$1,$2,...$10,$11...$n,获取当前执行脚本的第n个参数
$1,$2脚本后面接的第1,2个参数
[root@m01 scripts]# sh test.sh pp qq
pp qq大于9的,如$10需要加大括号
不加括号,$10成了识别成了$1+0的组合,也就是a0
[root@m01 scripts]# cat test.sh
#!/bin/bash
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
[root@m01 scripts]# bash test.sh  {a..z}
a b c d e f g h i a0 a1 a2 a3 a4 a5
加大括号后取到了12个字母
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12}
[root@m01 scripts]# bash test.sh  {a..z}
a b c d e f g h i j k l3.$#示例,表示当前shell脚本后面接的参数的总和
[root@m01 scripts]# cat test.sh
#!/bin/bash
echo $#
[root@m01 scripts]# sh test.sh gg
1
[root@m01 scripts]# sh test.sh  {1..100}
1004.$*与$@,当需要接收脚本后面所有参数时, 但是又不知道参数个数或参数太多就可以使用这两个变量
不加引号,二者无区别,用来获取脚本后所有参数
加引号,二者区别如下:
[root@m01 scripts]# cat test.sh
#!/bin/bas
for  arg in "$*"
doecho $arg
doneecho ------------for arg1 in "$@"
doecho $arg1
done
[root@m01 scripts]# sh test.sh  "i love" linux and python.
i love linux and python.
------------
i love
linux
and
python.
# 可以看出 "$*"输出结果是 "$1 $2 $3 ... $n"
# 而"$@" 输出结果是 "$1"  "#2"  "$3" ... "$n"

shell变量字串知识及实践

表达式 说明
${parameter} 返回变量$parametert的内容
${#parameter} 返回变量$parameter内容的长度(按字符),也适合特殊变量
${parameter:offset} 在变量${parameter}中,从位置offset之后开始提取子串到结尾
${parameter:offset:length} 在变量${parameter}中,从位置offset之后开始提取长度未length的子串
${parameter#word} 从变量${parameter}开头开始删除最短匹配的word子串
${parameter##word} 从变量${parameter}开头开始删除最长匹配的word子串
${parameter%word} 从变量${parameter}结尾开始删除最短匹配的word子串
${parameter%%word} 从变量${parameter}结尾开始删除最长匹配的word子串
${parameter/pattern/string} 使用string代替第一个匹配的pattern
${parameter//pattern/string} 使用string代替所有匹配的pattern

变量内容"子串"的删除和替换(重点)

====内容的删除====
[root@m01 ~]# url=www.sina.com.cn
1.${parameter}案例:获取变量内容
[root@m01 ~]# echo ${url}
www.sina.com.cn2.${#parameter}案例:获取变量值的长度
[root@m01 ~]# echo ${#url}
15====索引切片====
3.${parameter:offset}案例:在变量${parameter}中,从位置offset之后开始提取子串到结尾
[root@m01 ~]# echo ${url:2}
w.sina.com.cn
[root@m01 ~]# echo ${url:3}
.sina.com.cn4.${parameter:offset:length}案例:从变量${parameter}中从位置offset之后开始提取长度未length的子串
[root@m01 ~]# echo ${url:3:4}
.sin
[root@m01 ~]# echo ${url:1:3}
ww.5.${parameter#word}案例:从变量${parameter}开头删除最短匹配的word子串
[root@m01 ~]#  echo ${url#*.}
sina.com.cn
[root@m01 ~]#  echo ${url#*c}
om.cn6.${parameter##word}案例:${parameter}开头删除最长匹配的word子串
[root@m01 ~]#  echo ${url##*.}
cn
[root@m01 ~]#  echo ${url##*c}
n#发现没有删除内容,是因为从前往后,a.之前还有内容,写法错误,所以无法删除
[root@m1 ~]$ echo ${url#a.}
www.sina.com.cn
[root@m1 ~]$ echo ${url#*a.}   这样写就可以了
com.cn7.${parameter%word}案例:从变量${parameter}`结尾`开始删除`最短`匹配的word子串
[root@m01 ~]#  echo ${url%cn}
www.sina.com.
[root@m01 ~]#  echo ${url%.*}
www.sina.com
[root@m01 ~]#  echo ${url%m.cn}
www.sina.co8.${parameter%%word}案例:从变量${parameter}`结尾`开始删除`最长`匹配的word子串
[root@m01 ~]#  echo ${url%%.*}
www对比
[root@m01 ~]#  a=tianyun.1000phone.com
[root@m01 ~]# echo ${a%.*}  #匹配最短
tianyun.1000phone
[root@m01 ~]# echo ${a%%.*}  #匹配最长
tianyun===变量替换===
9.${parameter/pattern/string}案例:使用string代替第一个匹配的pattern
[root@m01 ~]# echo ${url/n/N}
www.siNa.com.cn
[root@m01 ~]# echo ${url/w/W}
Www.sina.com.cn10.${parameter//pattern/string}案例:使用string代替所有匹配的pattern
[root@m01 ~]# echo ${url//n/N}
www.siNa.com.cN
[root@m01 ~]# echo ${url//w/W}
WWW.sina.com.cn

shell特殊变量扩展知识

${parameter:-word}
如果parameter变量值为空或未赋值,就返回word字符串替代变量的值。冒号是可以省略的。
用途:如果变量为定义,则返回备用值,防止变量为空值或未定义而导致异常。
例:
[root@m01 ~]#  result=${test:-test1}
[root@m01 ~]#  echo $test [root@m01 ~]#  echo $result
test1
[root@m01 ~]#  echo $test [root@m01 ~]#
#以上说明短横线的作用:当变量值为空时,短横线后面的值会赋值给变量,当不为空时,不能覆盖原来的值
${变量名-新的变量名}
变量没有被赋值:会使用“新的变量值”替代
变量有被赋值(包括空值):不会被替代企业应用:防止变量为空从根删起--造成误删
find ${path:-/tmp} -name "*.log" -mtime +7|xargs rm -f
[root@m01 ~]# find ${path:-/tmp} -name "*.log"
/tmp/glances.log
[root@m01 ~]# path=/opt
[root@m01 ~]# find ${path:-/tmp} -name "*.log"
[root@m01 ~]# touch /opt/c.log
[root@m01 ~]# find ${path:-/tmp} -name "*.log"
/opt/c.log${parameter:=word}
如果parameter变量值为空或未赋值,就设置这个变量值为word,并返回其值。位置变量和特殊变量不适用。
用途:基本同上一个${parameter:-word} ,但是又额外给parameter变量赋值了。
例:
[root@m01 ~]# echo $test[root@m01 ~]# result=${test:=test1}
[root@m01 ~]# echo $result
test1
[root@m01 ~]# echo $test
test1
#当test值为空,test1的值不但会赋值给test还会赋值给result.${parameter:?word} 如果parameter变量值为空或未赋值,word字符串将被作为标准错误输出,否则输出变量的值。用途:用于捕捉由于变量未定义而导致的错误,并退出程序。
例如:
[root@m01 ~]# result=${test2:?变量内容为空}
-bash: test2: 变量内容为空
[root@m01 ~]# test2=xxx
[root@m01 ~]# echo $test2
xxx
[root@m01 ~]# result=${test2:?变量内容为空}
[root@m01 ~]# result=${test2:?变量内容为空}
#如果parameter值为空,就报错,否则就输出变量的值${parameter:+word}如果parameter变量值为空或未赋值,则什么都不做,否则word字符串替代变量的值。
例如:
[root@m01 ~]# result1=${test3:+heihei}
[root@m01 ~]# echo $result1[root@m01 ~]# echo $test3[root@m01 ~]# test3=333
[root@m01 ~]# result1=${test3:+heihei}
[root@m01 ~]# echo $result1
heihei
[root@m01 ~]# echo $test3
333
#意思就是test3值为空时,什么都不做,否则将值赋值给result1

shell进程特殊状态变量

状态变量 作用说明
$? 获取执行上一个指令的执行状态,返回值为0是成功,非0为失败
$$ 或者当前执行的shell脚本的进程号(PID)。(后面三个,了解即可)
$! 获取上一个在后台工作的进程的进程号(PID)
$__ 获取在此之前执行的命令或脚本的最后一个参数
案例:
[root@m01 ~]# pwd
/root
[root@m01 ~]# echo $?
0
[root@m01 ~]# pww
-bash: pww: command not found
[root@m01 ~]# echo $?
127

shell变量的数值计算实践

expr命令

expr是一款便打算计算工具,使用它完成表达式的求值操作

expr的常用运算:加减乘除,求模也就是取余运算%。
更多用法参考:man expr1.在shell编程中,常用来判断一个数是否为整数。
[root@m01 scripts]# cat test2.sh
#!/bin/bash
expr 2 + $1 &>/dev/null
if [ $? -eq 0 ]
thenecho "$1 is integer"
elseecho "$1 is noninteger"
fi
[root@m01 scripts]# sh test2.sh 1
1 is integer
[root@m01 scripts]# sh test2.sh 1.1
1.1 is noninteger2.通过expr判断文件扩展名
[root@m01 scripts]# cat expr1.sh
#!/bin/bash
expr "$1" : ".*\.txt" &>/dev/null
if [ $? -eq 0 ]
thenecho "$1 是文本"
elseecho "$1 不是文本"
fi
[root@m01 scripts]# sh expr1.sh hh.txt
hh.txt 是文本
[root@m01 scripts]# sh expr1.sh hh.html
hh.html 不是文本3.通过expr计算字符串的长度
[root@m01 scripts]# char="I love linux and python"
[root@m01 scripts]# expr length "$char"
23其他计算字符串长度的方法:
[root@m01 scripts]# echo ${#char}
23
[root@m01 scripts]# echo ${char} |wc -L
23
# -L 打印最长行的长度[root@m01 scripts]# echo ${char} |awk '{print length(($0))}'
23[root@m01 scripts]# echo ${char} |awk '{print length}'
23

算数运算

算数运算符 意义
+ - 加法或正号;减法或负号
* / % 乘法;除法;取余(取模)
** 幂运算
++ – 增加及减少,可以前置也可以放在变量结尾,默认步长为1
! && || 逻辑非(取反);逻辑与(and);逻辑或(or)
< <= > >= 比较符号,小于,小于等于,大于,大于等于
== != = 比较符号,相等,不相等,对于字符串"="也可以表示相等
<< >> 向左位移,向右位移
~ | & ^ 按位取反;按位异或;按位与;按位或
= += -= *= /= %= 赋值运算,例如a+=1等同a=a+1,a-=1等同a=a-1

bash编程常见运算命令汇总

运算操作符与运算命令 解释
(()) 用于整数运算的常用运算符,效率很高
let 用于整数运算,类似(())
expr 可以用于整数运算,还有其他的额外功能,如判断是否为整数
bc Linux下的一个计算器程序(适合整数以及小数运算)
$[] 用于整数运算
awk 即可用于整数运算,也可以用于小数运算
declare 定义变量值和属性,-参数可以用于定义整形变量,做运算
案例:
(())
[root@m01 scripts]# c=$((2*3))
[root@m01 scripts]# echo $c
6
[root@m01 scripts]# echo $((1+2*3-4/2))
5let
[root@m01 scripts]# let i=2+2
[root@m01 scripts]# echo $i
4expr
[root@m01 scripts]# expr 2 + 2
4
[root@m01 scripts]# expr2 + 2
-bash: expr2: command not found
[root@m01 scripts]# expr 2+ 2
expr: syntax error
[root@m01 scripts]# expr 2 +2
expr: syntax error
#前后必须有空格,使用称号时需要加反斜线,拼特定含义$[]
[root@m01 scripts]# echo $[2+2]
4bc
[root@m01 scripts]# 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'. 5.5-1.2
4.3
[root@m01 scripts]# echo 1.2*3|bc
3.6awk
[root@m01 scripts]# echo 1.1 0.9 |awk '{print $1 - $2}'
0.2
[root@m01 scripts]# echo 3.3 1.1 |awk '{print $1 / $2}'
3
[root@m01 scripts]# echo 3.3 1 |awk '{print $1 / $2}'
3.3

特殊内置命令read

从键盘读取变量值,通常在shell脚本中与用户交互的场合使用。该命令可以一次性读取多个变量的值,变量和输入的值都需要使用空格隔开。在read命令后面,如果没有指定变量名,读取的数据将被自动赋值给特定的变量REPLY。

参数:
-p 指定读取值时的提示符
-t 指定读取值时等待的时间,默认单位秒
-s 不回显
-n 输入字符个数案例:
[root@m01 scripts]# read -t 5 -p "请输入一个数值:" a
请输入一个数值:20
[root@m01 scripts]# echo $a
20shell案例
通过read方式读入整数变量,计算两个数的加减乘除幂模运算
[root@m01 scripts]# cat read.sh
#!/bin/bash
read -p "请输入两个整数:" a b
echo "a+b=$(($a+$b))"
echo "a+b=$(($a-$b))"
echo "a+b=$(($a*$b))"
echo "a+b=$(($a/$b))"
echo "a+b=$(($a**$b))"
echo "a+b=$(($a%$b))"
[root@m01 scripts]# sh read.sh
请输入两个整数:2 2
a+b=4
a+b=0
a+b=4
a+b=1
a+b=4
a+b=0也可以通过传参的方式
[root@m01 scripts]# cat read1.sh
#!/bin/bash
a=$1
b=$2
echo "a+b=$(($a+$b))"
echo "a+b=$(($a-$b))"
echo "a+b=$(($a*$b))"
echo "a+b=$(($a/$b))"
echo "a+b=$(($a**$b))"
echo "a+b=$(($a%$b))"
[root@m01 scripts]# sh read1.sh 2 2
a+b=4
a+b=0
a+b=4
a+b=1
a+b=4
a+b=0扩展1
[root@m01 scripts]# cat read.sh
#!/bin/bash
read -p "请输入两个整数:" a b c
if [ -z $a ]
thenecho "error1:必须是两个整数"exit
elif [ -z $b ]
thenecho "error2:必须是两个整数"exit
fiif [ -z $c ]
thenexpr $a + $b + 3 &>/dev/nullif [ $? -eq 0 ]thenecho "a+b=$(($a+$b))"echo "a+b=$(($a-$b))"echo "a+b=$(($a*$b))"echo "a+b=$(($a/$b))"echo "a+b=$(($a**$b))"echo "a+b=$(($a%$b))"elseecho "输入的不是整数"exitfi
elseecho "error3:必须是两个整数"
fi
[root@m01 scripts]# sh read.sh
请输入两个整数:1 2
a+b=3
a+b=-1
a+b=2
a+b=0
a+b=1
a+b=1
[root@m01 scripts]# sh read.sh
请输入两个整数:w 1
输入的不是整数
[root@m01 scripts]# sh read.sh
请输入两个整数:2 e
输入的不是整数
[root@m01 scripts]# sh read.sh
请输入两个整数:33 3 3
error3:必须是两个整数
[root@m01 scripts]# sh read.sh
请输入两个整数:1 2 3 4
read.sh: line 13: [: 3: binary operator expected
error3:必须是两个整数
[root@m01 scripts]# sh read.sh
请输入两个整数:1 1.1
输入的不是整数# 当脚本较为繁杂时,就不适合使用read,但是read和用户交互性较好。扩展2,使用传参的方式
[root@m01 scripts]# cat test.sh
#!/bin/bash
a=$1
b=$2
if [ $# -ne 2 ]
thenecho "只能输出两个整数"exit  1
elseexpr $a + $b + 3 &>/dev/nullif [ $? -eq 0 ]thenecho "a+b=$(($a+$b))"echo "a+b=$(($a-$b))"echo "a+b=$(($a*$b))"echo "a+b=$(($a/$b))"echo "a+b=$(($a**$b))"echo "a+b=$(($a%$b))"elseecho "输入的不是整数"exit 2fi
fi
[root@m01 scripts]# sh test.sh  1 2
a+b=3
a+b=-1
a+b=2
a+b=0
a+b=1
a+b=1
[root@m01 scripts]# sh test.sh  1 2 3
只能输出两个整数
[root@m01 scripts]# sh test.sh  w  2 3
只能输出两个整数
[root@m01 scripts]# sh test.sh  1  w  3
只能输出两个整数
[root@m01 scripts]# sh test.sh  1  2 e
只能输出两个整数
[root@m01 scripts]# sh test.sh  1.1 2
输入的不是整数

关于cat<<EOF的使用方法

cat<<EOF是从标准输入设备(一般为键盘)获取输入,在第二个EOF处结束输入,同时输出到输出设备(一般为显示器)。
例如:
[root@m01 scripts]#
[root@m01 scripts]# cat <<EOF
> This is test file!
> EOF
This is test file!
#结束的EOF必须是行首,否则被视为标准输入而不是结束分解符。

shell脚本的条件测试与比较

通常,在bash的各种条件结构和流程控制中都要进行各种测试,然后根据测试结果执行不同的操作,有时也会与if等条件语句相结合,来完成测试判断,减少程序运行的错误,执行测试条件表达式后通常会返回真或假,就像执行命令后的返回值为0和非0表示真假一样。

test命令

执行条件表达式

参数:
文件操作符
常用:
-a FILE 如果文件存在,则为true
-d FILE 如果文件是目录,则为true
-e FILE 如果文件存在,则为true
-f FILE 如果文件存在且为普通文件,则为true
-L FILE 如果文件是链接文件,则为true
-r FILE 如果文件可以读取,则为true
-s FILE 如果文件存在且不为空(大小不为0),则为true
-w FILE 如果文件可写,则为true
-x FILE 如果文件可以执行,则为true常用字符串运算符:
-z STRING 如果字符串为空,则为true
-n STRING 如果字符串不为空,则为true
STRING    如果字符串不为空,则为true
STRING1 = STRINFG2 如果字符串相等,则为true
STRING != STRING2  如果字符串不相等,则为true文件比较:
FILE1 -nt FILE2 根据修改日期,如果file1 比 file2 新,则为true
FILE1 -ot FILE2 根据修改日期,如果file1 比 file2 旧,则为true
FILE1 -ef FILE2 如果file1 为 file2的硬连接,则为true返回值:如果表达式执行结果为成功时返回0,当表达式执行结果为失败或给出非法参数时返回1。其他了解即可:
可参考:https://wangchujiang.com/linux-command/c/test.html
或者其他参考man 手册案例:
[root@m01 scripts]# test -a /etc/passwd
[root@m01 scripts]# echo $?
0
[root@m01 scripts]# test -a /etc/passddd
[root@m01 scripts]# echo $?
1

六种条件测试语法

条件测试语法 说明
test <测试表达式> test命令和 "<测试表达式>"之间至少有一个空格
[ <测试表达式> ] 单中括号边界和内容至少有一个空格
[[ <测试表达式> ]] 双中括号边界和内容之间至少有一个空格,比[]更新的语法格式;推荐使用
((<测试表达式>)) 双小括号一般用于if语句中,双小括号两端不需要有空格
(<测试表达式>) 小括号应用较少,了解即可
`<测试表达式>``` 通过反引号实现测试条件表达式,应用较少,了解即可
案例:
[root@m01 scripts]# [ -e /etc/passwd ] && echo 1 || echo 0
1
[root@m01 scripts]# [ -e /etc/psss ] && echo 1 || echo 0
0[root@m01 scripts]# [[ 1 -ne 2  ]] && echo 1 || echo 0
1
[root@m01 scripts]# [[ 2 -ne 2  ]] && echo 1 || echo 0
0

条件表达式的编程语法

[ <测试表达式> ] && 命令
如果前面的表达式成立,那么就执行后面的命令[ <测试表达式> ] || 命令
如果前面的表达式不成立,那么就执行后面的命令[ <测试表达式> ] && {
命令1
命令2
命令3
}
如果前面的表达式成立,那么就执行后面的命令[ <测试表达式> ] && 命令1 ||命令2
如果前面的表达式成立,那么就执行命令1,否则就执行命令2[ <测试表达式> ] && {
命令1
命令2
} || {
命令3
命令4
}
如果表达式成立,那么就执行命令1,2否则执行命令3,4

整数测试表达式

在[]以及test中使用的比较符号 在(())和[[]]中使用的比较符号 说明
-eq ==或= 相等全拼equal
-ne != 不相等全拼not equal
-gt > 大于 greater than
-ge >= 大于等于,greater equal
-lt < 小于,less than
-le <= 小于等于,less equal

逻辑测试表达式

在[]和test中使用操作符 在[[]]和(())使用操作符 说明
-a && and,与,两端都为真则真
-o || or,或,两端有一个为真则真
! not 非,相反则为真

条件表达式符号的语法对比

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ielgGMYT-1614393493074)(https://i.loli.net/2021/02/20/hyTE6tzMZdkFWln.png)]

vim编程环境配置

[root@m01 ~]# pwd
/root[root@m01 ~]# cat .vimrc
set nocompatible
set history=100
filetype on
filetype plugin on
filetype indent on
set autoread
set mouse=c
syntax enable
set cursorline
hi cursorline guibg=#00ff00
hi CursorColumn guibg=#00ff00
set foldenable
set foldmethod=manual
set foldcolumn=0
setlocal foldlevel=3
set foldclose=all
nnoremap <space> @=((foldclosed(line('.')) < 0) ? 'zc' : 'zo')<CR>
set expandtab
set tabstop=4
set shiftwidth=4
set softtabstop=4
set smarttab
set ai
set si
set wrap
set sw=4
set wildmenu
set ruler
set cmdheight=1
set lz
set backspace=eol,start,indent
set whichwrap+=<,>,h,l
set magic
set noerrorbells
set novisualbell
set showmatch
set mat=4
set hlsearch
set ignorecase
set encoding=utf-8
set fileencodings=utf-8
set termencoding=utf-8
set smartindent
set cin
set showmatch
set guioptions-=T
set guioptions-=m
set vb t_vb=
set laststatus=4
set pastetoggle=<F9>
set background=dark
set t_ti= t_te=
highlight Search ctermbg=black  ctermfg=white guifg=white guibg=black
autocmd BufNewFile *.py,*.cc,*.sh,*.java exec ":call SetTitle()"
func SetTitle()  if expand("%:e") == 'sh'  call setline(1, "#!/bin/bash")call setline(2, "##############################################################")  call setline(3, "# File Name: ".expand("%"))call setline(4, "# Version: V1.0")call setline(5, "# Author: daveorff")call setline(6, "# Organization:")call setline(7, "# Created Time : ".strftime("%F %T"))call setline(8, "# Description:")call setline(9, "##############################################################")endif
endfunc

shell脚本调试之sh命令

shell命令解释器

参数:
-c string 命令从-c后的字符串读取
-i 实现脚本交互
-n 进行shell脚本的语法检查
-x 实现shell脚本的逐条语句的跟踪应用
sh -n filename.sh    仅调试
sh -vx filename.sh   以调试的方式执行,查询整个执行过程
使用-x参数跟踪脚本调试shell脚本,能打印除所执行的每一行命令以及当前状态

if结构条件语句知识与实践

简单理解:如果…那么…否则…

单分支

if <条件表达式>
then指令
fi

双分支

if <条件表达式>
then指令
else指令2
fi

多分支

if条件多分枝结构主体为 "如果...,那么...,否则如果,那么,否则如果...那么...,...,否则..."if <条件表达式1>
then指令1
elif <条件表达式2>
then指令2
elif <条件表达式3>
then指令3
else指令4
fi

嵌套if

if <条件表达式1>
then指令1
else指令2if <条件表达式2>then指令3fi
fi
逻辑不清晰,不推荐使用,可以使用多个if分支。

实践

例1:如果不存在/backop目录就创建,存在则打印exist
[root@m01 scripts]# vim 01_01.sh #!/bin/bash
path="/backup"
if [[ -d $path ]]
thenecho "eixst"
elsemkdir $path -p
fi执行
[root@m01 scripts]# sh 01_01.sh
[root@m01 scripts]# sh 01_01.sh
eixst案例2:开发shell脚本判断系统剩余内存的大小,如果低于100MB就提示内存不足,否则提示内存充足
分析:先取内存
[root@m01 ~]# free -mtotal        used        free      shared  buff/cache   available
Mem:           3773         124        3488          11         160        3429
Swap:          1999           0        1999
字段结束:
total 内存总数
used  已经使用的内数
free  空闲的内存数
shared 是指共享的
buffes  是指缓冲内存数
cached  是指缓存内存数,单位是kb
关系:total=used+free使用awk取值
[root@m01 ~]# free -m | awk 'NR==2{print $4}'
3475再写if语句
[root@m01 scripts]# vim 02.sh
#!/bin/bash
mem=`free -m | awk 'NR==2{print $4}'`
if [[ $mem -le 100 ]]
thenecho "内存不足"
elseecho "内存充足"
fi#测试
[root@m01 scripts]# sh 02.sh
内存充足
[root@m01 scripts]# sh 02.sh
内存充足#改到4000测试
[root@m01 scripts]# sh 02.sh
内存不足案例3:
分别使用变量定义,read读入及脚本传参方式实现比较两个整数的大小
1.read读入方式:
解析:可以在传入的时候设置3个参数,以达到判断是否多出两个整数的目的
先使用rend读入两个整数  read -p "请读入两个整数:" a b c
判断输入整数个数是否小于2 方法:判断b是否为空 只有不为空继续下一步,否则退出
判断输入整数个数是否大于2,判断c是否为空,只有为空才进行下一步,否则退出
如果是再判断是否是两个整数 :如果两个数都是整数则进行下一步,否则退出
expr $a + $b + 3 &>/dev/null
如果都满足则比较大小
[root@m01 scripts]# cat 03_01.sh
#!/bin/bash
read -p "请输入两个整数:" a b c
if [[ -z $b ]]
thenecho "缺失一个数,请输入两个整数"exit 1
fiif [[ -n $c ]]
thenecho "参数个数大于2,请输入两个整数"exit 2
fiexpr  $a + $b + 1 &>/dev/null
if [[ $? -ne 0 ]]
thenecho "只能比较整数"exit 3
fiif [[ $a -lt $b ]]
thenecho "$a < $b"
elif [[ $a -gt $b ]]
thenecho "$a > $b"
elseecho "$a = $b"
fi使用传参的方式:
[root@m01 scripts]# cat 03_02.sh
#!/bin/bash
a=$1
b=$2
if [[ $# -ne 2 ]]
thenecho "参数个数不对,请输入两个整数"exit 1
fiexpr  $a + $b + 3 &>/dev/null
if [[ $? -ne 0 ]]
thenecho "只能比较整数"exit 2
fiif [[ $a -lt $b ]]
thenecho "$a < $b"
elif [[ $a -gt $b ]]
thenecho "$a > $b"
elseecho "$a = $b"
fi案例4:
打印一个菜单如下,当用户选择对应的数字时,就执行对应项目的应用
1.install lamp
2.install lnmp
3.exit[root@m01 scripts]# cat 04.sh
#!/bin/bash
cat<<EOF
1.install lamp
2.install lnmp
3.exit
EOF
read -p "请选择序号1|2|3:" num
expr $num + 2 &>/dev/null
if [[ $? -ne 0 ]]
thenecho "error1:请输入整数"exit
fiif [[ $num -eq 1 ]]
thenecho "install lamp..."
elif [[ $num -eq 2 ]]
thenecho "instahll lnmp..."
elif [[ $num -eq 3 ]]
thenecho "exit"exit
elseecho "请选择序号1~3"
fi嵌套if写法:
[root@m01 scripts]# cat 04_01.sh
#!/bin/bash
cat<<EOF
1.install lamp
2.install lnmp
3.exit
EOF
read -p "请选择序号1|2|3:" num
expr $num + 2 &>/dev/null
if [[ $? -ne 0 ]]
thenecho "error1:请输入整数"exit
elseif [[ $num -eq 1 ]]thenecho "install lamp..."elif [[ $num -eq 2 ]]thenecho "instahll lnmp..."elif [[ $num -eq 3 ]]thenecho "exit"exitelseecho "请选择序号1~3"fi
fi

shell函数的概念与作用及语法介绍

函数的概念与作用

简单来说,函数的作用就是将程序多次被调用的相同代码组合成函数体,并且为其取名,即函数名。当其他所有重复调用这部分代码的地方只需要用这个名字即可,当需要修改这部分重复代码时,也只需要改变函数体内的一部分代码即可实现所有调用的修改,也可以把函数单独的写入文件中,当需要调用函数时,再加载来使用。
使用shell函数的优势
- 把相同的程序段定义成函数,可以减少整个程序的代码里,提升开发效率
- 增加函数的可读性,易读性,提升管理效率
- 可以实现程序功能模块化,使得程序具备通用性,也就是可移植性
- 对应shell来说,Linux系统里近2000个命令都可以说是shell函数

**函数的多种语法 **

第一种语法:
function  函数名() {指令集...return n
}第二种语法:
function 函数名 {指令集return n
}第三种语法:(推荐)
函数名() {指令集...return n
}注意空格,return 函数返回值

函数的执行

不带参数的函数执行时,直接输入函数名即可(注意不带小括号)。(–简单函数执行)

案例:
[root@m01 scripts]# vim func1.sh
#!/bin/bash
function test_1() {echo "i am function_t1"
}function test_2 {echo "hello t2"
}test_3() {echo "hei t3"
}
test_1
test_2
test_3                                总结:;定义完函数后,直接使用其名字即可调用。

有关函数执行的重要说明

--执行shell函数时,函数名前的function和函数的小括号都不要带
--函数的定必须在执行前面定义或加载
--shell执行系统中各种程序的顺序为:系统别名-> 函数->系统命令->可执行文件
--函数执行时,会和调用它的脚本共用变量(相当于脚本的参数与函数共用),也可以为函数设定局部变量以及特殊位置参数
--在shell函数中,return命令功能与exit类似,作用是从函数中退出并返回函数值,而exit是退出脚本文件
--return语句会返回有关退出值(即返回值)给调用函数的当前程序,而exit会返回有关退出值(即返回值)给执行程序当前shell
--如果函数存放在单独的文件中,被脚本加载使用时,需要source或 . 点来加载
--在函数内一般使用local定义局部变量,这些变量离开函数即消失,不用local可以在脚本外调用。

**带参数的函数的执行方法格式如下: ** (–函数传参)

[root@m01 scripts]# cat func2.sh
#!/bin/bash
function test_1() {echo "i am $1"
}function test_2 {echo "$2"
}test_3() {echo "$3"
}
test_1 我是函数传参1
test_2 4 5 6
test_3 7 8 9
[root@m01 scripts]# sh func2.sh
i am 我是函数传参1
5
9

带参数的函数执行格式:

函数  参数1  参数2 ...

函数后接的参数说明

shell位置参数($1,$2,$3,...$#,$*,$?以及$@等)都可以作为函数的参数使用
此时父脚本的参数临时的被函数所掩盖或隐蔽
$0比较页数,它仍然是父脚本的名称
当函数执行完成时,原来的命令脚本参数即恢复
函数参数变量是函数体里面定义的#理解:
#比如$?的使用;可以查看函数的执行状态,状态码范围是0-255,且$?取值是脚本的最后一条命令的状态码
[root@m01 scripts]# cat func3.sh
#!/bin/bash
function gg {echo "hello gg"return 110
}
gg
[root@m01 scripts]# sh func3.sh
hello gg
[root@m01 scripts]# echo $?
110#local的使用;
[root@m01 scripts]# cat func4.sh
#!/bin/bash
function test_1 {local i="xiaoming"echo "i am $i"
}
test_1
echo $i
[root@m01 scripts]# sh func4.sh
i am xiaoming#从此输出为空,在函数内一般使用local定义局部变量,这些变量离开函数后即消失
[root@m01 scripts]#
#总结:
#使用local后在函数之外是无法调用函数体内的变量,把local去掉就是脚本变量是可以生效的。
#建议多个函数间定义同一个变量时使用local,这样多个函数间的同名变量便不会发生冲突。

将函数传参转为脚本传参 (–脚本传参)

[root@m01 scripts]# cat func6.sh
#!/bin/bash
daveff() {echo "i am $1"
}
daveff $1
[root@m01 scripts]# sh func6.sh superman
i am superman

将函数体和函数执行分成不同的文件

1.将函数写入系统函数,/etc/init.d/functions 写入此文件最后两行上面
例:
...fi
fifunction daveorff() {echo " I am $1"
}2.使用点 . 或source调用,地址为 /etc/init.d/functions
[root@m01 scripts]# cat func5.sh
#!/bin/bash
source /etc/init.d/functions
daveorff $13.测试,脚本链接什么参数,就输出什么内容
[root@m01 scripts]# sh func5.sh abcI am abc
[root@m01 scripts]# sh func5.sh cbaI am cba查看shell /etc/init.d/functios文件中所有的函数名grep -E "[a-zA-Z]+\(\)"  /etc/init.d/functions -o

总结:
函数总共有四种执行方式

1.简单函数与执行
2.带参数的函数编写执行
3.将函数传参转为脚本传参
4.将函数体和函数执行分成不同的文件,详见上文

函数案例

案例:
1.通过脚本传参的方式,检查web网站URL是否正常
解析:
wget命令
--spider  不下载任何大小;模拟爬虫
-q 安静访问  --quiet  安静模式(没有输出)
-o 把记录写的file文件中,加/dev/null表示不输出
-T 超时时间,设定响应超时的秒数
-t 重试,设定最大尝试连接次数(0表示无限制)
[root@m01 ~]# wget --spider -T 5 -q -o /dev/null -t 2 www.baidu.com
[root@m01 ~]# echo $?
0curl 命令
-l 值显示请求头信息
-s 静默模式,不输出任何东西 -S 显示错误
-o 把输出写到文件,加/dev/null表示不输出
-w % {http_code} 返回状态码,200为正常
-m 设置最大传输时间[root@m01 ~]# curl www.baidu.com -s &>/dev/null
[root@m01 ~]# echo $?
0
[root@m01 ~]# curl -l -m 5 -s -w "%{http_code}\n" -o /dev/bull www.baidu.com
200不用函数的的写法
[root@m01 scripts]# cat checkurl.sh
#!/bin/bash
wget --spider -T 5 -q -o /dev/null -t 2 $1
if [[ $? -eq 0 ]]
thenecho "$1 is ok"
elseecho "$1 is fail"
fi
[root@m01 scripts]# sh checkurl.sh  www.baidu.com
www.baidu.com is ok
[root@m01 scripts]# sh checkurl.sh  www.baidu.co
www.baidu.co is fail使用函数写法
[root@m01 scripts]# cat checkurl_01.sh
#!/bin/bash
usage(){echo "Usage: $0 url"exit 1
}checkurl(){wget --spider -T 5 -q -o /dev/null -t 2 $1if [[ $? -eq 0 ]]thenecho "is ok"elseecho "is fail"fi
}main(){if [[ $# -ne 1 ]]thenusageficheckurl $1
}
main $*
[root@m01 scripts]# sh checkurl_01.sh www.baidu.co
is fail
[root@m01 scripts]# sh checkurl_01.sh www.baidu.com
is ok

case结构条件语句

case结构条件语句相等于多分支的if/elif/else条件语句,但是它比这条件语句看起来更加规范工整,常被用于实现系统服务启动脚本等。

case 语法:
case "变量"  in值1)指令1...;;值2)指令2...;;值3)指令3...;;*)指令4...
esac

case条件语句的执行流程逻辑图

case条件语句的使用总结

1.case语句和if条件语句的适用性
case语句比较适合变量较少且为固定的数字或字符串集合的情况,而非不确定的的内容,如范围。如果便的值是已知固定的start/stop/restart等元素,那么采用case语句实现比较合适。2.case语句和if条件语句的常见应用场景
- case主要写服务的启动脚本,一般情况下,传参不同且具有少量的字符串,使用范围较窄
- if就是取值判断,比较,应用比case更广,几乎所有的case语句都可以使用if条件语句实现3.case语句的特定及优势
case语句就相当于多分支if/elif/else语句,单case语句的优势更规范,易读。

案例:

执行shell脚本,打印一个如下的水果菜单
1.apple
2.pear
3.banana
4.cherry
当用户输入对应的数字选择水果是,告诉他选择的水果是什么,并给水果单词加上一种颜色,使用case语句实现。[root@m01 scripts]# cat 06.sh
#!/bin/bash
cat << EOF
1.apple
2.pear
3.banana
4.cherry
EOFread -p "请选择序号:" num
case "$num" in1)echo -e "\033[31m apple \033[0m";;2)echo -e "\033[32m pear \033[0m" ;;3)echo -e "\033[33m banana \033[0m";;4)echo -e "\033[34m cherry \033[0m";;*)echo -e "\033[36m 请选择1~4 \033[0m"exit
esac

颜色代码

脚本中echo显示内容带颜色显示,echo显示带颜色,需要使用参数-e格式如下:
echo -e “\033[字背景颜色;文字颜色m字符串\033[0m”例如:
echo -e “\033[41;36m good \033[0m”
其中41的位置代表底色, 36的位置是代表字的颜色
1、字背景颜色和文字颜色之间是英文的冒号  ";"
2、文字颜色后面有个m
3、字符串前后可以没有空格,如果有的话,输出也是同样有空格内容的颜色用数字表示,范围为30-37,每个数字代表一种颜色。代码如下:
echo -e "\033[30m 黑色字 \033[0m" #<==30m表示黑色字。
echo -e "\033[31m 红色字 \033[0m" #<==31m表示红色字。
echo -e "\033[32m 绿色字 \033[0m" #<==32m表示绿色字。
echo -e "\033[33m 棕色字 \033[0m" #<==33m表示棕色字(brown),和黄色字相近。
echo -e "\033[34m 蓝色字 \033[0m" #<==34m表示蓝色字。
echo -e "\033[35m 洋红字 \033[0m" #<==35m表示洋红色字(magenta),和紫色字相近。
echo -e "\033[36m 蓝绿色 \033[0m" #<==36m表示蓝绿色字(cyan),和浅蓝色字相近。
echo -e "\033[37m 白色字 \033[0m" #<==37m表示白色字。给输出的字符串加不同的背景颜色:
字的背景颜色对应的数字范围为40-47,代码如下。
echo -e "\033[40;37m 黑底白字\033[0m"     #<==40m表示黑色背景。
echo -e "\033[41;37m 红底白\033[0m"       #<==41m表示红色背景。
echo -e "\033[42;37m 绿底白字\033[0m"     #<==42m表示绿色背景。
echo -e "\033[43;37m 棕底白字\033[0m"     #<==43m表示棕色背景(brown),和黄色背景相近。
echo -e "\033[44;37m 蓝底白字\033[0m"     #<==44m表示蓝色背景。
echo -e "\033[45;37m 洋红底白字\033[0m"   #<==45m表示洋红色背景(magenta),和紫色背景相近。
echo -e "\033[46;37m 蓝绿底白字\033[0m"   #<==46m表示蓝绿色背景(cyan),和浅蓝色背景相近。
echo -e "\033[47;30m 白底黑字\033[0m"     #<==47m表示白色背景。最后面控制选项说明
\033[0m 关闭所有属性
\033[1m 设置高亮度
\033[4m 下划线
\033[5m 闪烁
\033[7m 反显
\033[8m 消隐
\033[30m — \33[37m 设置前景色
\033[40m — \33[47m 设置背景色
\033[nA 光标上移n行
\033[nB 光标下移n行
\033[nC 光标右移n行
\033[nD 光标左移n行
\033[y;xH设置光标位置
\033[2J 清屏
\033[K 清除从光标到行尾的内容
\33[s 保存光标位置
\033[u 恢复光标位置
\033[?25l 隐藏光标   
\033[?25h 显示光标
;;
3)echo -e "\033[33m banana \033[0m";;
4)echo -e "\033[34m cherry \033[0m";;
*)echo -e "\033[36m 请选择1~4 \033[0m"exit

esac


### 颜色代码

脚本中echo显示内容带颜色显示,echo显示带颜色,需要使用参数-e

格式如下:
echo -e “\033[字背景颜色;文字颜色m字符串\033[0m”

例如:
echo -e “\033[41;36m good \033[0m”
其中41的位置代表底色, 36的位置是代表字的颜色
1、字背景颜色和文字颜色之间是英文的冒号 “;”
2、文字颜色后面有个m
3、字符串前后可以没有空格,如果有的话,输出也是同样有空格

内容的颜色用数字表示,范围为30-37,每个数字代表一种颜色。代码如下:
echo -e “\033[30m 黑色字 \033[0m” #<==30m表示黑色字。
echo -e “\033[31m 红色字 \033[0m” #<==31m表示红色字。
echo -e “\033[32m 绿色字 \033[0m” #<==32m表示绿色字。
echo -e “\033[33m 棕色字 \033[0m” #<==33m表示棕色字(brown),和黄色字相近。
echo -e “\033[34m 蓝色字 \033[0m” #<==34m表示蓝色字。
echo -e “\033[35m 洋红字 \033[0m” #<==35m表示洋红色字(magenta),和紫色字相近。
echo -e “\033[36m 蓝绿色 \033[0m” #<==36m表示蓝绿色字(cyan),和浅蓝色字相近。
echo -e “\033[37m 白色字 \033[0m” #<==37m表示白色字。

给输出的字符串加不同的背景颜色:
字的背景颜色对应的数字范围为40-47,代码如下。
echo -e “\033[40;37m 黑底白字\033[0m” #<==40m表示黑色背景。
echo -e “\033[41;37m 红底白\033[0m” #<==41m表示红色背景。
echo -e “\033[42;37m 绿底白字\033[0m” #<==42m表示绿色背景。
echo -e “\033[43;37m 棕底白字\033[0m” #<==43m表示棕色背景(brown),和黄色背景相近。
echo -e “\033[44;37m 蓝底白字\033[0m” #<==44m表示蓝色背景。
echo -e “\033[45;37m 洋红底白字\033[0m” #<==45m表示洋红色背景(magenta),和紫色背景相近。
echo -e “\033[46;37m 蓝绿底白字\033[0m” #<==46m表示蓝绿色背景(cyan),和浅蓝色背景相近。
echo -e “\033[47;30m 白底黑字\033[0m” #<==47m表示白色背景。

最后面控制选项说明
\033[0m 关闭所有属性
\033[1m 设置高亮度
\033[4m 下划线
\033[5m 闪烁
\033[7m 反显
\033[8m 消隐
\033[30m — \33[37m

设置前景色
\033[40m — \33[47m 设置背景色
\033[nA 光标上移n行
\033[nB 光标下移n行
\033[nC 光标右移n行
\033[nD 光标左移n行
\033[y;xH设置光标位置
\033[2J 清屏
\033[K 清除从光标到行尾的内容
\33[s 保存光标位置
\033[u 恢复光标位置
\033[?25l 隐藏光标  
\033[?25h 显示光标


shell编程快速入门(一)相关推荐

  1. Shell 编程快速入门

    什么是Shell脚本? Shell脚本(英语:Shell script)是一种电脑程序与文本文件,内容由一连串的shell命令组成,经由Unix Shell直译其内容后运作.被当成是一种脚本语言来设计 ...

  2. shell编程快速入门及实战

    shell编程:对于hadoop程序员,通常需要熟悉shell编程,因为shell可以非常方便的运行程序代码. 1.shell文件格式:xxx.sh #!/bin/sh ---shell文件第一行必须 ...

  3. Linux Bash Shell编程快速入门

    BASH 的基本语法 最简单的例子 -- Hello World! 关于输入.输出和错误输出 BASH 中对变量的规定(与 C 语言的异同) BASH 中的基本流程控制语法 函数的使用 2.1     ...

  4. Shell编程从入门到入土

    1. Shell 编程的作用 将一些复杂的命令简单化(平时我们提交一次github代码可能需要很多步骤,但是可以用Shell简化成一步) 可以写一些脚本自动实现一个工程中自动更换最新的sdk(库) 自 ...

  5. C++网络编程快速入门(四):EPOLL模型使用

    目录 基本使用方法 step1:创建epollfd step2:将fd绑定到epollfd step3:调用epoll_wait检测事件 epoll_wait与poll.select区别所在 水平触发 ...

  6. C++网络编程快速入门(二):Linux下使用select演示简单服务端程序

    目录 select参数解释 select使用规范 select使用缺点 基本流程 实例代码 通信效果演示 往期文章 select参数解释 extern int select (int __nfds, ...

  7. Java NIO 非阻塞网络编程快速入门

    NIO 非阻塞网络编程快速入门 案例: 编写一个 NIO 入门案例,实现服务器端和客户端之间的数据简单通讯(非阻塞) 目的:理解 NIO 非阻塞网络编程机制 import java.net.InetS ...

  8. 转载博客:generic netlink 编程快速入门

    https://segmentfault.com/a/1190000016220770 generic netlink 编程快速入门

  9. pdf python 3.7编程快速入门 潘中强_无python基础,这些书籍可以帮您快速入门。

    利用Python进行数据分析> 定 价:119 元 作者:韦斯·麦金尼(Wes McKinney)著;徐敬一译 ISBN:9787111603702 出 版 社:机械工业出版社 学习Python ...

最新文章

  1. matlab生成多组多维高斯分布数据
  2. 华为FusionCompute-VRM密码重置
  3. 《算法竞赛进阶指南》打卡-基本算法-AcWing 95. 费解的开关:位运算、枚举、递推
  4. case study
  5. Effective Java之用EnumSet代替位域(三十二)
  6. c语言printf里的自增,笔试题记录:C语言——函数printf()的执行机制;先自增与后自增的区别;取值运算与自增运算的优先级...
  7. pythoncsv格式列变换_用Python将csv行转换为列
  8. Linux打包压缩.md
  9. 安装Lync Server 2013
  10. 全面接触PDF:最好用的PDF软件汇总(2010-12-07更新)
  11. 射频微波芯片设计6:射频电路中的噪声概论
  12. matlab图片测量尺寸_基于视觉的零件尺寸测量方法
  13. 图像篡改被动检测技术一览:基于特征提取和卷积神经网络的篡改检测
  14. Android UI设计之十三自定义ScrollView,实现QQ空间阻尼下拉刷新和渐变菜单栏效果
  15. 安卓后门工具:backdoor-apk 教程
  16. JavaScript(第四天)—爱创课堂专业前端培训
  17. 2022年前端面试集锦
  18. Selenium Python2.7
  19. Caj论文转pdf(带书签目录)
  20. 如何用网页脚本追踪用户

热门文章

  1. eclipse配置https
  2. 钉钉桌面版绑定其他邮箱
  3. html5 css3制作柱形图,一步一步教你实现纯CSS的柱形图
  4. MacBook 连接投影仪
  5. Cesium实现UnrealBloom泛光效果
  6. C# 添加Word页眉、页脚和页码
  7. 蘑菇云「行空板Python入门教程」第七课:舒尔特方格小游戏
  8. 拯救智慧城市:要智商还有生气
  9. python 等腰三角形的性质_Blender 脚本之 Operator 初探
  10. sqlserver连接池及查看连接数相关