目录
3.2 临时生效在进入文件后输入:set number 和1效果相同,但是是临时
5.18 & 后台运行命令 Run job in background
5.19 - 减号Minus 连字符Hyphen、破折号Dash
一.什么是shell
什么是shell呢?shell是用C语言编写的程序,它是用户使用 Linux 的桥梁。Shell既是一种命令语言,又是一种程序设计语言。简单来说Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。也可以这样认为,linux中的shell就是linux内核的一个外层保护工具,并负责完成用户与内核之间的交互
二.bash的注意事项
1.shell命名:shell脚本名称一般为英文,大写,小写,后缀以.sh结尾
2.不能使用特殊符号、空格
3.shell编程,首行必须以 #!/bin/bash
4.SHELL脚本变量,不能以数字,特殊符号开头,可以使用下划线,但是不能使用破折号
三.vi/vim
Linux是一个万物文件的一个操作系统,在这里介绍一下vim/vi,基本上分为三种模式一般命令模式,编辑模式与命令模式。
对于初学者来说最好是添加行号,这有两种方法
3.1在 /etc/vimrc中修改配置文件,永久生效
vim /etc/vimrc #修改配置文件,永久生效
set number #在配置文件的最后一行添加
3.2 临时生效在进入文件后输入:set number 和1效果相同,但是是临时
3.3最终的效果

四.热身脚本(先跟着敲,踏出第一步)
4.1清除日志1.0版本
1 #!/bin/bash
2 #清除日志
3 #要以root身份运行
4 cd /var/log
5 cat /dev/null > messags
6 cat /dev/null > wtmp
7 echo "Logs cleaned up."
4.2清除日志2.0版本
1 #!/bin/bash
2 #清除日志
3 #要以root身份运行,如果不是root,会自定义的错误提示,然后退出
4 # 使用变量,这样更加灵活,优雅
5 LOG_DIR=/var/log
6 cd $LOG_DIR
7 cat /dev/null > messags
8 cat /dev/null > wtmp
9 echo "Logs cleaned up."
10 exit #这个命令是正确,合适的退出的办法
11 #不带任何参数的exi,将返回退出的状态码
4.3清除日志3.0版本
1 #!/bin/bash
2 # 清除日志
3 # 要以root运行,如果不是root,会自定义的错误提示,然后退出
4 #如果使用变量,这样更加灵活,优雅
5 LOG_DIR=/var/log
6 ROOT_UID=0 # $UID为0,用户为root权限
7 LINET=50 # 默认的保存的行数
8 E_XCD=66 # 退出代码:表示不能修改目录位置
9 E_NOROOT=67 #退出代码:表示不是root用户
10 # 以root身份来运行这个脚本
11 if [ "$UID" -ne "$ROOT_UID" ]
12 then
13 echo " Must be root run this script."
14 exit $E_NOROOT
15 fi
16 # 测试是否给这个脚本传递有参数(非空)
17 if [ -n "$1" ]
18 then
19 lines=$1
20 else
21 lines=$LINES #如果没有在命令指定,就使用默认值
22 fi
23 cd $LOG_DIR
24 #如果处理log file 之前,应当确定当前目录是否正确
25 #如果不在/var/log目录中
26 if [ `pwd` != "$LOG_DIR" ] # 或 if [ "pwd" !="$LOG_DIR" ]
27 then
28 echo "Can't change $LOG_DIR"
29 exit $E_XCD
30 fi
31 #保留mssage文件中的最后部分,而不是全部清除
32 tail -$lines messages > mesg.tmp
33 mv mesg.tmp messages
34 # 旧的办法,不在需要了,新的办法更加安全吗?
35 # cat /dev/null > messages
36 cat /dev/null > wtmp
37 echo "Logs cleaned up."
38 exit 0
39 #退出时返回0,0表成功
脚本敲完了之后,热身就结束了,学习脚本,要边敲边理解,一定一定一定要手敲
五.进入学习脚本的一步,学习注释符
5.1“#”
1 #!/bin/bash
2 # This is a comment.
3 echo "A comment will follow " # 注释在这里
4 # 注意上一条语句中,#号前面要有一个空格
5 # A tab precede this comment
6 # 注意上一条语句中,注释是放在本行 行首空白的后面
7 # echo中被引号的#,是不能被当作的注释的
8 # echo中被转义的#,是不能被当作的注释的
9 #反斜线是转义字符
10 echo "111-双引号 The # here does not begin a comment."
11 echo "222_单引号 The # here does not begin a comment."
12 echo 333_无引导且有转义 The \# here does not begin a comment.
13 echo 444_无引导无转义 The # here begin a comment.
14 # 在特定的参数替换结构中,#号不是注释
15 echo ${PATH#*:} #效果:将第一个冒号之前的删除
16 # 在数字常量表达式中,#号不是注释
17 echo $((2#101011)) # 数制转换,2进制转换为10进制,这不是注释
5.2“;”命令分隔符 ,在同一行上写两个或者多个命令
1 #!/bin/bash
2 #分号(separator [semicolon])测试
3 echo hello ; echo there
4 filename="ftt.txt"
5 if [ -e "filename " ] ; then #注意:if 和 then 需要分离
6 echo "File $filename exists." ; cp $filename $filename.bak
7 else
8 echo "File $filename not found." ; touch $filename
9 fi ; echo "File test complete"
双分号,是case代码块的结束
case word in
模式1)
命令序列;;
模式2)
命令序列;;
........... *)
命令序列n;;
esac
case语句支持多个条件的匹配,语法格式如下:
case word in
模式1|模式2|模式3)
命令序列1;;
模式4|模式5|模式6)
命令序列2;;
... ... *)
命令序列n;;
esac
功能描述:使用case进行字母比较
在括号前面的内容与后面的命令序列之间,可以使用回车键换行,也可以没有换行
请输入一个a~c之间的字母
使用;&会执行后一个模式匹配中的命令
使用;;&会继续对后面的模式进行匹配
所以屏幕会继续显示后面的字母
1 #!/bin/bash
2 #双分号
3 variable='abc'
4 case "$variable" in
5 adc)
6 echo "\$variable = abc";;
7 sxz)
8 echo "\$variable = sxz";;
9 esac
10 exit
5.3句号 .
[root@server1 ~]# vim ftt.txt
f=sxzftt
x=fttsxz
t=123456
1 #!/bin/bash
2 #点命令测试,点命令与source命令效果相同
3 . ftt.txt #加载一个数据文件
4 # 这与source ftt.txt 效果相同
5 #ftt.txt必须存在于当前目录
6 #下面,引用数据文件中定义的一个变量
7 echo f
8 exit
5.4引号: “” 部分引用 ‘’全引用
[root@server1 ~]# echo $PWD
/root
[root@server1 ~]# echo "$PWD"
/root
[root@server1 ~]# echo '$PWD'
$PWD
1 #!/bin/bash
2 #引号练习 + 变量赋值练习
3 a=ftt
4 s=$a
5 #------------------------------------------------------------
6 #强烈注意:赋值时,等号前后一定要不要有空格
7 #1,如果等号前面有空格?
8 #VARIABLE =value
9 #将执行带一个参数=value的命令 VARIABLE
10 #如果等号后面有空格?
11 # VARIADLE= value
12 #将执行后面这个小写的value命令,并且一个赋值为“”的变量VARIADLE
13 #-------------------------------------------------------------
14 echo s # 这不是一个变量,所以只会输出s
15 echo $s
16 echo "$s" #结果同上一行
17 echo "$s"
18 echo '$s'
19 echo
20 exit
5.5逗号 用于连接多个算术操作,并返回最后一项
[root@server1 ~]# let "t1 = ((a = 9,15/3))"
[root@server1 ~]# echo "tl = $t1"
tl = 5
[root@server1 ~]# let "t1 = ((a = 5+3,7-1,15-3))"
[root@server1 ~]# echo "t1=$t1"
t1=12
[root@server1 ~]# let "t3=((a=9,15/3))"
[root@server1 ~]# echo "t3=$t3 a=$a"
t3=5 a=9
5.6斜线
\反斜线 backslash 转义符
| \n | 新的一行 |
| \r | 回车 |
| \t | 水平制表符 |
| \v | 垂直制表符 |
| \b | 后退符 |
| \a | “alert” (蜂鸣或者闪烁) |
| \0xx | 转换为八进制的ASCLL码,等价于0xx |
/正斜线 forward slash
文件名路径分隔符 例:/etc/yum.repos.d
除法算法操作符
5.7反引号
返引号 back quote,命令替换
1 #!/bin/bash
2 #本脚本的名称为:fan.sh
3 #用于测试反引号back quote的命令替换commnad substitution功能
4
5 echo $0
6 script_name=`basename $0`
7 echo script_name
8
9 script_name=`basename -s .sh $0`
10 echo script_name
11 exit
5.8冒号colon,空命令null command
1 #!/bin/bash
2 #实例代码:冒号colon,空命令 null command
3 # 例1 死循环
4 #while : #本行等同于 while true
5 #do
6 #echo word
7 #done
8 # 例2 : #if/then的占位符 placeholder
9 if condition
10 then : #什么都不做,引出分支,有可能以后补充
11 else
12 take-some-action
13 fi
14 #例3:清空一个文件,但不会修改该文件的权限,也cat /dev/null类似
15 # 由于空命令是一个内建的命令,所以不会生产一个新进程
16 : >> ftt.txt
5.9感叹号
!取反操作符reverse
反转命令的退出状态码
反转测试操作符的意义
正确的代码千遍一律,错误的代码千奇百怪
例如:
[root@server1 ~]# cd
[root@server1 ~]# echo $? 正确且运行成功的查看为0
0
[root@server1 ~]# cdd
-bash: cdd: 未找到命令
[root@server1 ~]# echo $? 错误的就千奇百怪了
127
1 #!/bin/bash
2 # 叹号!取反操作符 与退出状态码的练习
3 # ture 与冒号都是什么不做的命令
4 true
5 echo "Exit status of \"true\" =$?"
6 ! true #注意感叹号!与命令之间空格
7 echo "Exit status of \"true\" =$?"
8 #退出状态码必须是十进制数,范围是0-255
9 exit 88
5.10 星* asterisk
1.文件名通配符 wild card、globbing
[root@server1 ~]# ls -l * 相当于ll *在里面的作用是查找所有文件
[root@server1 ~]# ls -l [ab]* 查找开头为a和b的所有文件
[root@server1 ~]# ls -l [a-c]* 查找开头为a到c的所有文件
[root@server1 ~]# ls -l [^ab]* 查找除了a和b之外的所有文件
[root@server1 ~]# ls -l {b*,c*,*est*} 查找文b和以及文件中带有est的所有文件
在这补充一个额外的千万千万不要尝试,俗称删库跑路
[root@server1 ~]# rm -rf /*
2.正则表达哦式,metacharacter、regular expression
匹配任意个数(包含0个)的字符
例:1133* 匹配11加一个或多个三
3.乘法 multiplication
** 幂 exponentiation
5.11问号 ? question mark
1.文件名通配符 wild card、globbing
[root@server1 ~]# ls -l t?.sh 匹配单个字符,t1,t1……
2.正则表达式,metacharacter、regular expression
匹配它前面的字符,1次或0次。通常用来匹配单个字符
3.测试操作符test operator
(1).在双圆括号结构表达式中,用来测试一个条件的结果(三元操作符 三个条件if-then-else)
{((…))双圆括号结构
a.于let命令很相似,允许算术扩展和赋值
[root@server1 ~]# a=$((5+3))
[root@server1 ~]# echo $a
8
b.在bash中,使用C语言风格变量操作的一种处理机制
(( a= 23)) # 变量赋值,“=”两边允许有空值
(( a++ )) #后置自加
(( a-- )) #后置自减
(( ++a )) #前置自加
(( --a )) #前置自减 }
[root@server1 ~]# (( var0 = var1<98?9:21)) var这个变量如果下于98那就把9赋值给var0,否者就是21
[root@server1 ~]# echo $var0
9
1 if [ "$var0" -lt 98 ] #-lt less then 小于
2 then
3 var1=9
4 else
5 var1=21
6 fi
这个两种输出结果一样,但是三元的代码量减少不少
(2).在参数替代表达式中,用来测试一个变量是否被设置
$ {} 参数替代(方法的其中之一) parameter substitution
如果变量未被声明或赋值,那么就输出错误信息(错误信息是可以指定的)
$ {parameter?err_msg} 如果变量未声名
$ {parameter:?err_msg} 如果变量声明了,但未赋值……
a.正常地进行变量定义与赋值
[root@server1 ~]# var1=123
[root@server1 ~]# echo $var1
123
[root@server1 ~]# echo ${var1}
123
b.变量未定义
[root@server1 ~]# echo ${var2}
[root@server1 ~]# echo ${var2?err_msg} (错误信息指定的是err——msg)
-bash: var2: err_msg
[root@server1 ~]# echo ${var2:?err_msg}
-bash: var2: err_msg
c.进定义了变量,但未赋值
[root@server1 ~]# var3=
[root@server1 ~]# echo ${var3}
[root@server1 ~]# echo ${var3:?ll}
-bash: var3: ll
如果一个环境变量或自定义变量没有被定义……
- 问题 :#正常地进行变量定义与赋值
[root@server1 ~]# ORA_HOME=""
[root@server1 ~]# if [ $ORA_HOME="" ] ; then echo "111" ; fi
111
2.问题:如果如果没有定义变量
[root@server1 ~]# if [ $ORA_HOME="" ] ; then echo "111" ; fi
111
这两个都没有特别直观的查看一个变量是否被赋值
解决方法:
使用问号 ?来测试一个变量是否被设置
如果没有被设置,就输出一个错误退出脚本
这个错误可以自定义
1 #!/bin/bash
2 #使用参数替换和错误信息
3 #例1:检查一些系统环境变量,这是一个预防性保护的好习惯
4 # 例如:如果$USER没有被设置,系统将无法识别你
5 : ${HOSTNAME?} ${USER?} ${HOME?} ${MALL}
6 #向NULL命令传递四个测试
7 echo
8 echo "Name of then machine is $HOSTNAME"
9 echo "You are "$USER""
10 echo "Your home directory is $HOME"
11 echo "Your mail INBOX is located in $MALL"
12 echo
13 echo "If you are reading this messags"
14 echo "critical environmental vatiables have benn set"
15 echo
16 echo
17 #例2:#[variable?] 结构也能检查脚本中变量的设置情况
18 ThisVariable=Value-of-ThisVariable
19 : "Variable of ThisVaiable is $ThisVariable"
20 echo
21 echo
22 : ${SF?"SF ha not been set."}
23 #如果SF没有被设置的话,那么这个脚本会打印一个错误消息,然后退出
24 #你可以自己指定错误消息
25 # : ${variablenaem?"ERROR MESSAGE"}
26 #和上面的测试方法一样于下面的效果相同
27 # dummy_variable=${sxz}
28 # dummy_variable=${sxz?"sxz has not been set."}
29 # echo ${sxz} > /dev/null
30 #bash的设置值 set -u 可以强制检查变量是否被设置的方法
31 echo "You will not sess this message,because script already terminated."
32
33 HERE=0
34 exit $HERE不会在这里面退出
35 #事实上,这个脚本将会返回值1作为退出状态($echo $?)

默认情况下bash是检查variable是否被使用
例[root@server1 ~]# echo $ll
[root@server1 ~]# echo $cc
这个是不报错的
[root@server1 ~]# set -u 打开bash检查variable是否使用
[root@server1 ~]# echo $cc
-bash: cc: 为绑定变量
[root@server1 ~]# set +u 关闭
[root@server1 ~]# echo $c
5.12美元符号$
$的用途
1.$ 变量替换(引用的内容) Variable substitution
1.1 变量的名字就是变量保存值的地方
1.2 引用变量的值就叫做变量替换
[root@server1 ~]# variable=123
[root@server1 ~]# echo variable
variable
[root@server1 ~]# echo $variable
123
[root@server1 ~]# echo ${variable}
123
1.3 在一些情况下,变量没有前缀名$
1.3.1变量被声明或赋值
1.3.2 变量被unset
1.3.3 变量被export
1.3.4 变量代表一种信号(发给进程的一个简单消息,目的是:通知目的进程采取一系列的指令动作)
1.4 在引用时,$的变化
1.4.1 单引号(‘ ’),强引用,保持字面意思
1.4.2 双引号(“ ”),弱引用,发生变量替换
2.$ 正则表达式中的行结束符 Regular expression
在RE中用来匹配行尾,例:
“abc$” 匹配行尾的abc
“^$” 匹配空行
3.$ { } 参数替代 Parameter substitution
3.1如果变量未被声明或赋值,那么就输出错误信息(错误信息是可以指定的)
$ {parameter?err_msg} 如果变量未声名
$ {parameter :? err_msg} 如果变量声明了,但未赋值……
3.2如果变量未被声明或赋值,那么就替换为默认值
${ parameter-default } 是否被声明,如果没有就指定为默认值
${ parameter:-default } 是否被赋值,如果没有就把default指定为变量
1 #!/bin/bash
2 #variable.sh
3 # 一个变量是否被声明或设置,将会影响变量是否使用默认值
4 # 情况1:没有声明,直接使用
5 echo "username1 has not declared."
6 echo "Test1A: username1 = ${username1-`whoami`}" #有输出
7 echo "Test1A: username1 = ${username1:-`whoami`}" #有输出
8 echo
9 #情况2:声明了变量,但变量值为空null
10 username2=
11 echo "username2 has been declared,but is set ton null."
12 echo "Test2B: username2 = ${username2-`whoami`}" #无输出
13 echo "Test2B: username2 = ${username2:-`whoami`}" #有输出
14 #有输出,因为:-会比-多了一个测试条件

4.$ ‘ … ‘ 引用字符串扩展 Ouoted string expansion bash 默认时十进制
[root@server1 ~]# quote=$'\042' 42八进制 转义到字符为“
[root@server1 ~]# echo $quote
"
5.$#,$*,$@位置参数 pcsitional parameters
5.1 $0,$1,$2,等的
位置参数,从命令行传递到脚本,或者传递给函数
5.2$#
命令行参数或者位置参数的个数
5.3$*
所有的位置参数都被看作一个单词
5.4$@
与$*相同,但是每个参数都是一个独立的引用字符串
6.$?退出状态码变量 Exit status variable
7.$ 进程ID变量 process ID variable
5.13圆括号()parentheis
1.命令组
[root@server1 ~]# a=123 父进程
[root@server1 ~]# (echo "a = $a"; a=321; echo "a = $a") 子进程
a = 123
a = 321
[root@server1 ~]# echo "a = $a" 只能读取父进程
a = 123
2.数组初始化
Array=(element1 element2 elemet2)
5.14大括号,花括号 brace
1.扩展 expansion
1 #!/bin/bash
2 #把file1,file2,file3连接在一起,并且定向到combined_file中
3 cat {file1,file2,file3} > combined_file
4 #拷贝“file1.txt”到“file1.bakkup” 中
5 cp file1.{txt,bakkup}
6 #输出26个英文字母,阿拉伯数字
7 echo {a..z} {0...11}
2.代码块 Block of code
2.1变称为inline group,相当于创建了一个匿名函数(没有名字的函数)
2.2 与“标准” 函数不同,在其声明的变量,对于脚本其他部分的来说是可见的
1 #!/bin/bash
2 #大括号代码块 和 IO重定向
3 #从/etc/fstab中读行
4 File=/etc/fstab
5 {
6 read line1
7 read line2
8 } < $File
9 echo "First line if $File is:"
10 echo "$line1"
11 echo
12 echo "First line if $File is:"
13 echo "$line2"
14 exit 0

安装rpm脚本
1 #!/bin/bash
2 #6-1rpm.sh
3 #获得一个rpm文件的描述,文件列表,将检查是否已经安装
4 #并将结果保存到一个文件中
5 #此脚本通过一个代码块来实现
6 SUCCESS=0
7 E_NOARGS=65
8 #判断是否给此脚本传递参数
9 if [ -z "$1" ]
10 then
11 echo "Usage: `basename S0` rpm-file "
12 exit $E_NOARGS
13 fi
14 {
15 echo
16 echo "Archive Description:"
17 rpm -qpi $1 #rpm文件的描述
18 echo
19 echo "Archive Listing:"
20 rpm -qpl $1 #rpm中文件列表
21 echo
22 rpm -i --test $1 #检查rpm包是否可以安装
23 if [ "$?" -eq $SUCCESS ]
24 then
25 echo "$1 can be installed."
26 else
27 echo "$1 cannot be installed."
28 fi
29 echo
30 } > "$1.text" #将代码块的所有输出重定向到文件中
31 echo "Results of rpm test in file $1.test"
32 exit 0
[root@server1 ~]# ./6-1rpm.sh origin-pod-3.7.1-2.el7.x86_64.rpm
[root@server1 ~]# more origin-pod-3.7.1-2.el7.x86_64.rpm
安装rpm2.0判断rpm是否存在如果没有就直接退出
1 #!/bin/bash
2 #6-1rpm.sh
3 #获得一个rpm文件的描述,文件列表,将检查是否已经安装
4 #并将结果保存到一个文件中
5 #此脚本通过一个代码块来实现
6 SUCCESS=0
7 E_NOARGS=65
8 E_NOFILE=66
9 #判断是否给此脚本传递参数
10 if [ -z "$1" ]
11 then
12 echo "Usage: `basename S0` rpm-file "
1 #!/bin/bash
2 #6-1rpm.sh
3 #获得一个rpm文件的描述,文件列表,将检查是否已经安装
4 #并将结果保存到一个文件中
5 #此脚本通过一个代码块来实现
6 SUCCESS=0
7 E_NOARGS=65
8 E_NOFILE=66
9 #判断是否给此脚本传递参数
10 if [ -z "$1" ]
11 then
12 echo "Usage: `basename S0` rpm-file "
13 exit $E_NOARGS
14 fi
15 #判断文件是否存在
16 if [ ! -f "$!"]
17 then
18 echo "$1 not exist"
19 exit $E_NOFILE
20 fi
21 {
22 echo
23 echo "Archive Description:"
24 rpm -qpi $1 #rpm文件的描述
25 echo
26 echo "Archive Listing:"
27 rpm -qpl $1 #rpm中文件列表
28 echo
29 rpm -i --test $1 #检查rpm包是否可以安装
30 if [ "$?" -eq $SUCCESS ]
31 then
32 echo "$1 can be installed."
33 else
34 echo "$1 cannot be installed."
35 fi
36 echo
37 } > "$1.text" #将代码块的所有输出重定向到文件中
38 echo "Results of rpm test in file $1.test"
39 exit 0
40
vim -d 文件1 文件2 对比文件的不同
3.{}\;路径名 pathname
[root@server1 ~]# find . -name "*.cfg"
./anaconda-ks.cfg
[root@server1 ~]# find . -name "*.cfg" -exec cp {} /tmp \;
[root@server1 ~]# ls /tmp/*.cfg
/tmp/anaconda-ks.cfg
5.15 方括号,中括号 bracket [ ]
1.条件测试 Test
1 #!/bin/bash
2 echo "Testing \"0\""
3 if [ 0 ] # zero
4 then
5 echo "0 is true."
6 else #Or else ...
7 echo "0 is false."
8 fi # 0 is true.

2.扩展测试[[ ]] test
1 #!/bin/bash
2 file=/etc/passwd
3 if [[ -e $file ]] #exist
4 then
5 echo "Password file exists."
6 fi
![]()
3.数组元素 Array element
[root@server1 ~]# Array[1]=slot_1
[root@server1 ~]# echo ${Array[1]}
slot_1
4.字符范围 Range of characters
[syz] 匹配字符s,x或z
[c-n] 匹配字符c到字符n之间的任意一个字符
[B-Pk-y] 匹配从B到P,或者从k到之间的任意一个字符
[a-z0-9] 匹配任意小写字母或数字
[^b-d] 将会匹配范围在b到d之外的任意一个字符
[Yy] [Ee] [Ss] 能够匹配yes,Yes,YES,yEs,等等
[0-9] [0-9] [0-9]-[0-9]-[0-9]-[0-9] [0-9] [0-9] [0-9] 匹配美国的社保码
5.16 大于号与小于号 > &> >& >> < <>
1.重定向 redirection
| 重定向操作符 | 功能 |
| < 文件名 | 重定向输入 |
| >文件名 | 重定向输出 |
| >> 文件名 | 追加输出 |
| 2> 文件名 | 重定向标准错误输出 |
| 2>> 文件名 | 重定向和追加标准错误输出 |
| &>> 文件名 | 重定向标准输出和标准错误输出(首选方式*) |
| >& 文件名 | 重定向标准输出和标准错误输出 |
| 2>&1 | 将标准错误输出重定向到标准输出的去处 |
| 1>&2 | 将输出重定向到标准错误输出的去处 |
| >| | 重定向输出时忽略noclobber -c noclobber 可以防止重定向时覆盖文件 |
| <> 文件名 | 如果是一个设备文件,使用文件作为标准输入和标准输出 |
注意:
a.stdin、stdout和stderr的文件描述符分别时0,1,2
b.文件描述符与>之间没有空格
c.文件描述符默认值是1,1>可以简写为>
d.>后面的文件描述符前面一定要有&,否则会当作普通文件
f.&>file 与>& file意思完全相同,都等价于>file 2>&1
例:
Scriptname > filename
Scriptname >> filename
Scriptname 2>&1
Command &> filename
Command 1>&2 简写为 command >&2
Ls 2>a1 >&1 等同于 ls >a1 2>&1
2.进程替换 process substitution
2.1命令替换:把一个命令的结果赋值给一个变量
[root@server1 ~]# dir_contents=`ls -al`
[root@server1 ~]# echo $dir_contents
2.2进程替换:把一个进程的输出提供给另一个进程
> (command)
< (command)
3.比较操作符 comparison operator
3.1字符串比较,安装ASCLL字符进行排序来比较
1 #!/bin/bash
2 # ASCII 字符<>比较
3 veg1=carrots
4 veg2=tomatoes
5 if [[ "$veg1" < "$vge2" ]]
6 then
7 echo "$veg1 < $vge2"
8 else
9 echo "What kind of dictionary are yon using,anywho?"
10 fi
11
12 exit 0
![]()
3.2 整数比较
5.17竖线
1. | 管道 pipe
[root@server1 ~]# cat *.sh | sort | uniq
[root@server1 ~]# cat file1 file2 | ls -l | sort
2. || 或-逻辑操作OR logical operator
在条件测试结构中,如果条件测试结构两边中的任意一边结果为true的话,||操作就会返回0(代表执行成功)
5.18 & 后台运行命令 Run job in background
1.命令后面跟一个&,表示在后台运行
例:[root@server1 ~]# sleep 10 &
[1] 1579
[root@server1 ~]# ps aux | grep sleep
root 1579 0.0 0.0 107948 348 pts/0 S 17:30 0:00 sle
root 1581 0.0 0.0 112720 984 pts/0 S+ 17:30 0:00 g
[root@server1 ~]# ps aux | grep sleep
root 1583 0.0 0.0 112720 984 pts/0 S+ 17:31 0:00 gre
[1]+ 完成 sleep 10
1 #!/bin/bash
2 #l.sh
3 for i in 1 2 3 4 5 6 7 8 9 10 # 第一循环
4 do
5 echo -n "$i"
6 done & # 在后台执行这个循环
7 echo
8
9 for i in 11 12 13 14 15 16 17 18 19 20 #第二个循环
10 do
11 echo -n "$i"
12 done # 正常地在前台执行这个循环
13 echo
14 exit 0

2.&&与-逻辑操作AND logical operator
在条件测试结构的两边结构都为true时,&&才返回0(代表success)
5.19 - 减号Minus 连字符Hyphen、破折号Dash
1、选项,前缀 option,prefix
例:ls -al
1 #!/bin/bash
2 if [ $file1 -ot $file2]
3 then
4 echo "File $file1 is older than $file2."
5 fi
6
7
8 param2=${param1:-$DEFAULTVAL}
2.重定向stdin或stdout Redirection
例:
[root@server1 ~]# echo "whatever" | cat -
Whatever
[root@server1 ~]# bunzip1 -c 1.tar.bz2 | tar xvf –
[root@server1 ~]# (cd /source/directory && tar cf - .) | (cd /dest/directory && tar xpvf -)
[root@server1 ~]# cp -a /source/directory* /dest/directory
[root@server1 ~]# cp -a /source/directory* /source/directory/.[^.]* /dest/directory
[root@server1 ~]# file l.sh
![]()
1 #!/bin/bash
2 cp /root/file1 data.txtt
3 file=data.txt
4 head $file
5 # 要插入的头的内容
6 title="***This is the title of data text file***"
7 echo $title | cat - $file > $file.new
8
9 head data.txt.new
10 exit 0
![]()
例:备份最近一天当前目录下所有修改的文件
1 #!/bin/bash
2 # 备份最近一天当前目录下所有修改的文件
3 # 使用-的stdin,stdout,及tar-gzip的手段
4 # 默认的备份文件名,嵌入当前的时间
5 BACKUPFILE=backup-$(date +%Y-%m-%d)
6 # 如果没有传递参数给此脚本,则使用默认的文件名
7 archive=${1:-$BACKUPFILE}
8 tar cvf - `find . -mtime -1 -type f -print`> $archive.tar
9 gzip $archive.tar
10 # 如果当前目录中文件过多,或文件名包括空格时,有可能执行失败
11 # 可以考虑修改为:
12 # find . -mtime -1 -type f -print0 | xargs -0 tar rvf "$archive.tar"
13 echo "Directory $PWD backup up in archive file \"$archive.tar.gz\"."
14 exit 0

[root@server1 ~]# tar -ztf backup-2022-06-03.tar.gz

3.先前的工作目录 Previous working directory
Cd – 回到先前的工作目录,其实时使用环境变量$ OLDPWD
4.减号 Minus
5.20 等号= Equal
1.等号 Equal
[root@server1 ~]# a=28
[root@server1 ~]# echo $a
28
2.字符串比较操作 String Comparison operator
1 #!/bin/bash
2 a=123
3 b=12
4 if [ "$a" = "$b" ]
5 then
6 echo yes
7 else
8 echo on
9 fi

5.21 加号+ plus
1.加法算术 Addition arithmetic operator
2.正则表达式 regular expression
echo a11b | sed -ne `/a1\+b/p`
echo a11b | grep `a1\+b`
echo a11b | gawk `a1\+b`
3.选项 option
[root@server1 ~]# echo $l
[root@server1 ~]# set -u
[root@server1 ~]# echo $l
-bash: l: 为绑定变量
[root@server1 ~]# set +u
[root@server1 ~]# echo $l
5.22 %百分号 percen
1.取模 modulo
[root@server1 ~]# expr 5 % 3
2
[root@server1 ~]# expr 5 % 4
1
2.模式匹配 pattern matching
[root@server1 ~]# echo ${var%Pattern}
[root@server1 ~]# echo ${var%%Pattern}
5.23 ~ 波浪号 Tilde
1.~ 家目录 Home
$HOME
2.~+ 当前工作目录 current working directory
$PWD
3.~- 先前的工作目录 previous working directory
$OLDPWD
4.=~正则表达式匹配 regular expression match
5.24 ^ 脱字号,补字号 caret
1.行首 Beginning of line
2.大写抓换 Uppercase conversion
[root@server1 ~]# bash –version bash版本在四以后

[root@server1 ~]# var=varMixedUpVariable
[root@server1 ~]# echo ${var}
varMixedUpVariable
[root@server1 ~]# echo ${var^} 第一个字母大写
VarMixedUpVariable
[root@server1 ~]# echo ${var^^} 全部大写
VARMIXEDUPVARIABLE
3.控制字符 control characters
348

被折叠的 条评论
为什么被折叠?



