egrep、bash环境配置及脚本、vim编辑器

egrep及扩展的正则表达式

egrep = grep -E

egrep [options] pattern [file..]

扩展正则表达式的元字符
字符匹配
.:匹配任意单个字符
[root@localhost ~]# grep -E . /tmp/123
ABC
123
boy

[]:匹配指定范围内的单个字符
[root@localhost ~]# grep -E [abc] /tmp/123
boy
abc

[^]:匹配指定范围外的单个字符
[root@localhost ~]# grep -E [^abc] /tmp/123
ABC
123
boy

次数匹配:
:匹配前面的字符任意次
[root@localhost ~]# grep -E "a
b" /tmp/mytest
b
ab
aab
aaab

?:匹配前面的字符0次或1次
[root@localhost ~]# grep -E "a?b" /tmp/mytest
b
ab
aab
aaab

+:匹配前面的字符1次或多次
[root@localhost ~]# grep -E "a+b" /tmp/mytest
ab
aab
aaab

{m}:匹配前面的字符m次
[root@localhost ~]# grep -E "a{2}b" /tmp/mytest
aab
aaab

{m,n}:匹配前面的字符至少m次,至多n次
[root@localhost ~]# grep -E "a{2,3}b" /tmp/mytest
aab
aaab

扫描二维码关注公众号,回复: 430241 查看本文章

锚定
^:锚定行首
[root@localhost ~]# grep -E "^root" /etc/passwd
root:x:0:0:root:/root:/bin/bash

$:锚定行尾
[root@localhost ~]# grep -E "bash$" /etc/passwd
root:x:0:0:root:/root:/bin/bash
rocket:x:507:507::/home/rocket:/bin/bash
allen:x:701:701::/home/allen6:/bin/bash

\<或\b:锚定词首
[root@localhost ~]# grep -E "\<root" /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

\>或\b:锚定词尾
[root@localhost ~]# grep -E "root\>" /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

分组
():括号中的字符串作为分组,并后向引用,\1,\2,...

或者
a|b:C|cat 表示C或cat

练习:
1、显示当前系统root、centos、user1用户的默认shell和UID
[root@localhost ~]# grep -E "^(root|centos|user1)\>" /etc/passwd | cut -d: -f3,7
0:/bin/bash
707:/bin/bash
708:/bin/bash

2、找出/etc/rc.d/init.d/functions文件(centos)中某单词后面跟一个小括号的行
[root@localhost ~]# grep -E -o "[_[:alpha:]]+()" /etc/rc.d/init.d/functions

3、使用echo输出一绝对路径,使用egrep取出器路径基名;并且使用egrep取出路径的目录名,类似于dirname命令的结果
[root@localhost ~]# echo "/etc/passwd" | grep -E -o "[^/]+/?$" | cut -d"/" -f1
[root@localhost ~]# echo "/etc/passwd/" | grep -E -o "[^/]+/?$" | cut -d"/" -f1

4、找出ifconfig命令结果中1-255之间的数值
ifconfig | grep -E --color=auto "\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>"

5、找出ifconfig命令结果中的IP地址

fgrep "" 不支持正则表达式搜索
[root@localhost ~]# fgrep --color=auto "root" /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

bash的基础特性(4)

变量类型:数据存储格式、存储空间大小、参与运算种类

字符型
数值型(整型、浮点型)

强类型:定义变量是必须指定类型,参与运算必须符合类型要求,调用未声明变量会产生错误;例如:C
弱类型:无须指定类型,默认均为字符型,参与运算会自动进行隐式类型转换;例如:bash

bash中的变量的种类:
根据变量的生效范围的标准划分:
本地变量:生效范围为当前shell进程,对当前shell之外的其他shell进程,包括当前shell的子shell进程均无效
环境变量:生效范围为当前shell进程及其子进程
局部变量:生效范围为当前shell进程中某代码片段(通常指函数)
位置变量:$1、$2...来表示,用于让脚本在脚本代码中调用通过命令行传递给它的参数
特殊变量:$?、$0

本地变量:
变量赋值:name=‘value’
可以使用引用
value:
(1)可以是直接字串 name=‘username’
[root@localhost ~]# name=tom
[root@localhost ~]# echo $name
tom

(2)变量引用 name=‘$username’
[root@localhost ~]# name1="allen $name"
[root@localhost ~]# echo $name1
allen tom

(3)命令引用 name=command name=$(command)
[root@localhost ~]# name2=head -1 /etc/passwd | cut -d: -f1
[root@localhost ~]# echo $name2
root

[root@localhost ~]# name=$(tail -1 /etc/passwd | cut -d: -f1)
[root@localhost ~]# echo $name
centos

变量引用:${name},$name
[root@localhost ~]# echo $name
centos
[root@localhost ~]# echo ${name}
centos

"" 弱引用,其中的变量引用会被替换为变量值;
[root@localhost ~]# echo "$SHELL"
/bin/bash
‘’ 强引用,其中的变量引用不会被替换为变量值,而保持原字符串
[root@localhost ~]# echo '$SHELL'
$SHELL

显示已定义的所有变量:set
销毁变量:unset name
[root@localhost ~]# name=tom
[root@localhost ~]# echo $name
tom
[root@localhost ~]# unset name
[root@localhost ~]# echo $name

环境变量
变量声明,赋值
export name=value
declare -x name=value
[root@localhost ~]# export name=allen
[root@localhost ~]# echo $name
allen

[root@localhost ~]# declare -x name=ben
[root@localhost ~]# echo $name
ben

变量引用:$name、${name}
[root@localhost ~]# echo $name
ben
[root@localhost ~]# echo ${name}
ben

显示所有变量
export
env
printenv

销毁变量:unset name
[root@localhost ~]# unset name
[root@localhost ~]# echo $name

bash有许多內建的环境变量:PATH SHELL UID HISTSIZE HOME PWD HISTFILE PS1

变量命名法则:
1、不能使用程序中的保留字,例如:if、for等
2、只能使用数字,字母及下划线,且不能以数字开头;
3、见名知义

只读变量:
readonly name
declare -r name
[root@localhost ~]# name=kidd
[root@localhost ~]# readonly name
[root@localhost ~]# name=hill
-bash: name: readonly variable

[root@localhost ~]# name=curry
[root@localhost ~]# declare -r name
[root@localhost ~]# name=hill
-bash: name: readonly variable

位置变量:
在脚本代码中调用命令行传递给脚本的参数
$1、$2、... 对应调用第1、第2等参数
[root@localhost tmp]# cat a.sh
#!/bin/bash

echo $1 $2

[root@localhost tmp]# . a.sh tom mary
tom mary
[root@localhost tmp]# . a.sh 10 20
10 20

shift [n] 剔除位置变量 位置变量替岗
[root@localhost tmp]# cat a.sh
#!/bin/bash

echo $1
shift 1
echo $1
shift 1
echo $1

[root@localhost tmp]# . a.sh tom mary kidd
tom
mary
kidd
[root@localhost tmp]# . a.sh 10 20 30
10
20
30
$0 命令本身
[root@localhost tmp]# cat a.sh
#!/bin/bash

echo $0

[root@localhost tmp]# bash /tmp/a.sh
/tmp/a.sh

$* 传递给脚本的所有参数
$@ 传递给脚本的所有参数
$# 传递给脚本的参数的个数
[root@localhost tmp]# cat a.sh
#!/bin/bash

echo $*
echo $@
echo $#

[root@localhost tmp]# . a.sh 10 20 30
10 20 30
10 20 30
3

示例:判断给出的文件的行数
#!/bin/bash
linecount="$(wc -l $1 | cut -d' ' -f1)"
echo "$1 has $linecount lines."

[root@localhost tmp]# cat a.sh
#!/bin/bash

linecount=wc -l $1 | cut -d' ' -f1
echo "$1 has $linecount lines."
[root@localhost tmp]# . a.sh /etc/passwd
/etc/passwd has 31 lines.

bash的配置文件
按生效范围划分,存在两类:
全局配置:
/etc/profile、/etc/profile.d/*.sh、/etc/bashrc
个人配置:
~/.bash_profile、~/.bashrc

按功能划分,存在两类
profile类:为交互式登录的shell提供配置
全局 /etc/profile、/etc/profile.d/*.sh
个人 ~/.bash_profile
功用:1、用于定义环境变量、2、运行命令或脚本

bashrc类:为非交互式登录的shell提供配置
全局 /etc/bashrc
个人 ~/.bashrc
功用:1、定义命令别名、2、定义本地变量

shell登录:
交互式登录:
直接通过终端输入账号密码登录;
使用"su - username" 或"su -l username"切换的用户
读取配置文件的次序 /etc/profile -- /etc/profile.d/*.sh -- ~/.bash_profile -- ~/.bashrc -- /etc/bashrc

非交互式登录:
su username
图形界面打开的终端
执行脚本
读取配置文件的次序 ~/.bashrc -- /etc/bashrc -- /etc/profile.d/*.sh

编辑配置文件定义的新配置的生效方式
1、重新启动shell进程
2、使用source或.命令进程

问题:
1、定义对所有用户都生效的别名;/etc/bashrc
2、让用户的PATH环境变量的值多出一个路径,例如多出/usr/local/apache2/bin
管理员 export PATH=$PATH:/usr/local/apache/bin
所有用户
/etc/profile.d/path.sh
export PATH=$PATH:/usr/local/apache/bin

~/.bash_profile
export PATH=$PATH:/usr/local/apache/bin

bash中的算术运算

      • / % **(乘方)

实现算术运算
1、let var=算术表达式
[root@localhost ~]# num1=10
[root@localhost ~]# num2=20
[root@localhost ~]# let num3=num1+num2
[root@localhost ~]# echo $num3
30

2、var=$[算术表达式]
[root@localhost ~]# num3=$[$num1-$num2]
[root@localhost ~]# echo $num3
-10

3、var=$((算术表达式))
[root@localhost ~]# num3=$(($num1*$num2))
[root@localhost ~]# echo $num3
200

4、var=$(expr arg1 arg2 arg3)
[root@localhost ~]# num3=$(expr $num2 / $num1)
[root@localhost ~]# echo $num3
2

乘法符号在某些场景中需要转义

bash有內建的随机生成器:$RANDOM
[root@localhost ~]# echo $RANDOM
2756
[root@localhost ~]# echo $[$RANDOM/2]
10492

增强型赋值
+=、-=、*=、/=、%=

let varOPERvalue
例如:let count+=1

自增、自减
let var+=1
let var++

let var-=1
let var--

练习1:写一个脚本
计算/etc/passwd文件中的第10个用户和第20个用户的ID之和
[root@localhost ~]# cat /tmp/a.sh
#!/bin/bash

num1=head -10 /etc/passwd | tail -1 | cut -d: -f3
num2=head -20 /etc/passwd | tail -1 | cut -d: -f3

num3=$[$num1+$num2]
echo "the sum is $num3."
[root@localhost ~]# . /tmp/a.sh
the sum is 517.

练习2:写一个脚本
传递两个文件路径作为参数给脚本,计算这两个文件中所有空白行之和
[root@localhost ~]# cat /tmp/a.sh
#!/bin/bash

num1=grep "^[[:space:]]*$" $1 | wc -l
num2=grep "^[[:space:]]*$" $2 | wc -l

echo "the spacelinesum is $[$num1+$num2]."

[root@localhost ~]# . /tmp/a.sh /etc/fstab /etc/issue
the spacelinesum is 2.

练习3:统计/etc、/var、/usr目录共有多少个一级子目录和文件
[root@localhost ~]# cat /tmp/a.sh
#!/bin/bash

num1=ls /etc | wc -l
num2=ls /var | wc -l
num3=ls /usr | wc -l

echo "the filecounts is $[$num1+$num2+$num3]."

[root@localhost ~]# . /tmp/a.sh
the filecounts is 172.

条件测试:
判断某需求是否满足,需要由测试机制来实现

注意:专用的测试表达式需要由测试命令辅助完成测试过程;

测试命令:
test expression
[root@localhost ~]# test 10 -lt 20
[root@localhost ~]# echo $?
0
[root@localhost ~]# test 10 -gt 20
[root@localhost ~]# echo $?
1

[ expression ]
[root@localhost ~]# [ 10 -lt 20 ]
[root@localhost ~]# echo $?
0

[[ expression ]]
[root@localhost ~]# [[ 10 -gt 20 ]]
[root@localhost ~]# echo $?
1

注意:expression 前后必须有空白字符

bash的测试类型
数值测试:
-gt 是否大于
[root@localhost ~]# test 10 -gt 20
[root@localhost ~]# echo $?
1

-ge 是否大于等于
[root@localhost ~]# test 10 -ge 20
[root@localhost ~]# echo $?
1

-eq 是否等于
[root@localhost ~]# test 10 -eq 20
[root@localhost ~]# echo $?
1

-ne 是否不等于
[root@localhost ~]# test 10 -ne 20
[root@localhost ~]# echo $?
0

-lt 是否小于
[root@localhost ~]# test 10 -lt 20
[root@localhost ~]# echo $?
0

-le 是否小于等于
[root@localhost ~]# test 10 -le 20
[root@localhost ~]# echo $?
0

字符串测试
== 是否等于
[root@localhost ~]# test abc == ABC
[root@localhost ~]# echo $?
1

是否大于
[root@localhost ~]# test abc > ABC
[root@localhost ~]# echo $?
0

< 是否小于
[root@localhost ~]# test abc < ABC
[root@localhost ~]# echo $?
0

!= 是否不等于
[root@localhost ~]# test abc != ABC
[root@localhost ~]# echo $?
0
=~ 左侧字符串是否能够被右侧的pattern所匹配,注意:此表达式一般用于[[ ]]中
[root@localhost ~]# [[ "root" =~ ^r ]]
[root@localhost ~]# echo $?
0

-z "string" 测试字符串是否为空,空则为真,不空则为假
[root@localhost ~]# name=tom
[root@localhost ~]# [ -z "$name" ]
[root@localhost ~]# echo $?
1

-n "string" 测试字符串是否不空,不空则为真,空则为假
[root@localhost ~]# [ -n "$name" ]
[root@localhost ~]# echo $?
0

bash自定义退出状态码
exit [n] 自定义退出状态码
注意:脚本中一旦遇到exit 命令,脚本会立即终止,终止退出状态取决于exit命令后面的数字
[root@localhost ~]# cat /tmp/a.sh
#!/bin/bash

cat /etc/issue &> /dev/null
catt /etc/issue &> /dev/null
exit 1

[root@localhost ~]# . /tmp/a.sh
[root@localhost ~]# echo $?
1

注意:如果未给出脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码
[root@localhost ~]# cat /tmp/a.sh
#!/bin/bash

cat /etc/issue &> /dev/null
catt /etc/issue &> /dev/null

[root@localhost ~]# . /tmp/a.sh
[root@localhost ~]# echo $?
127

练习:写一个脚本
接受一个文件路径作为参数
如果参数个数小于1,则提示用户"至少应该给一个参数",并立即退出;
如果参数个数不小于1,则显示第一个参数所指向的文件中的空白行数;
[root@localhost ~]# cat /tmp/a.sh
#!/bin/bash

[ $# -lt 1 ] && echo "usage:$0 argu1"
[ $# -ge 1 ] && grep "^[[:space:]]*$" $1 | wc -l
[root@localhost ~]# . /tmp/a.sh
usage:-bash argu1
[root@localhost ~]# . /tmp/a.sh /etc/fstab
1
[root@localhost ~]# . /tmp/a.sh /etc/fstab /etc/passwd
1

vim编辑器
vi visual interface 文件编辑器
文本:ASCII unicode
文本编辑种类:
行编辑器 sed
全屏编辑器 nano

vim vi improved vi的增强版
vim 模式化的编辑
基本模式
编辑模式,也称作命令模式
输入模式
末行模式:内置的命令行接口

打开文件:
vim [option]... file...
+# 打开文件后,直接让光标处于第#行的行首
+/PATTERN 打开文件后,直接让光标处于第一个被PATTERN匹配到的行的行首

模式转换
编辑模式 --> 输入模式
i insert 在光标所在处输入
a append 在光标所在处后面输入
o 在当前光标所在行的下方打开一个新行
I 在当前光标所在行的行首输入
A 在当前光标所在行的行尾输入
O 在当前光标所在行的上方打开一个新行

输入模式 --> 编辑模式
ESC

编辑模式 --> 末行模式
:

末行模式 --> 编辑模式
ESC

关闭文件
:q 退出
:q! 强制退出,丢弃做出的修改
:wq 保存退出
:x 保存退出
:w /path/to/somewhere 另存为另外一个文件,该文件可为已存在文件,亦可为不存在文件

ZZ 保存退出 编辑模式的保存退出

光标跳转
字符间跳转
h 向左跳转 l 向右跳转 j 向下跳转 k 向上跳转

#command 跳转由#指定的个数的字符 即跳转#个字符

单词间跳转
w 下一个单词的词首
e 当前或下一个单词的词尾
b 当前或前一个单词的词首

#command 由#指定一个跳转的单词数 即跳转#个单词

词首词尾跳转
^ 跳转至行首的第一个非空白字符
0 跳转至行首
$ 跳转到行尾

行间跳转
#G 跳转至由#指定行 跳转至第#行
G 跳转至最后一行
1G或gg 跳转至第一行

句间移动
) 跳转至下一句
( 跳转至上一句

段落间移动
} 跳转至下一段
{ 跳转至上一段

vim的编辑命令
x 删除光标处的字符
#x 删除光标处起始的#个字符

xp 交换光标所在处的字符及其后面字符的位置

替换命令(r replace)
r 替换光标所在处的字符

删除命令
d 删除命令,可结合光标跳转字符使用,实现范围删除
d$ d^ d0
dw de db

#command 删除#个字符

dd 删除光标所在处的行
#dd 删除多行

粘贴命令(p put paste)
p 缓冲区中存储的如果为整行,则粘贴至当前光标所在行的下方,否则,则粘贴至当前光标所在处的后面
P 缓存区中存储的如果为整行,则粘贴至当前光标所在行的上方,否则,则粘贴至当前光标处在出的前面

复制命令(y yank)
y 复制,工作行为相似于d命令
y$ y ^ y0
yw ye yb

#command 复制#个字符

yy 复制光标所在处的行
#yy 复制多行

改变命令(c change)
c 修改
编辑模式 --> 输入模式
工作行为相似于d命令
c$ c^ c0
cw ce cb

#command 修改#个字符

cc 删除行并输入新内容
#cc 删除#行并输入新内容

其他编辑操作

可视化模式
v 按字符选定
V 按行选定

注意 经常结合编辑命令使用 d c y

撤销此前的编辑
u (undo) 撤销此前的操作
#u 撤销指定次数的操作

撤销此前的撤销
ctrl+r

重复前一个编辑操作
.(点号)

翻屏操作
ctrl+f 向文件尾部翻一屏
ctrl+b 向文件首部翻一屏

ctrl+d 向文件尾部翻半屏
ctrl+u 向文件首部翻半屏

vim自带的练习教程 vimtutor

vim的末行模式 內建的命令行接口

1、地址定界
:start_pos,end_pos

具体第#行,例如2表示第2行

#,# 从左侧#表示起始行,到右侧#表示行结尾
#,+# 从左侧#表示的行起始,加上右侧#表示的行数
. 当前行
$ 最后一行
.,$-1 表示当前行-倒数第二行
% 全文,相当于1,$

/pat1/,/pat2/ 从第一次被pat1模式匹配到的行开始,一直到第一次被pat2匹配到的行结束
#,/pat/ 从第#行开始到第一次被pat匹配到的行结束
/pat/,$ 从第一次被pat匹配到的行开始到文本的最后一行结束

使用方式:后跟一个编辑命令
d 删除
y 复制
w /path/to/somewhere 将范围内的行另存到指定的文件中 该文件可以是已经存在,或者不存在
r /path/from/somefile 在指定位置插入指定文件中的所有内容

2、查找字符串
/pattern 从当前光标所在处向文件尾部查找
?pattern 从当前光标所在处向文件首部查找
n 与命令同方向查找下一个
N 与命令反方向查找下一个
注意:亦可使用正则表达式查找字符串

3、查找并替换
s 在末行模式下完成查找替换操作
s /要查找的内容/替换为的内容/修饰符
要查找的内容 可使用模式
替换为的内容 不能使用模式,但可以使用\1,\2,... 等后向应用符号,还可以使用"&"引用前面查找时查找到的整个内容
修饰符:
i 忽略大小写
g 全局替换,默认情况下,每一行只替换第一次出现的内容br/>查找替换中的分隔符/可替换为其他字符,例如
s@@@
s###

练习:
1、复制/etc/grub2.cfg至/tmp/目录,用查找替换命令删除/tmp/grub2.cfg文件中的行首的空白字符
:%s/^[[:space:]]+//g

2、复制/etc/rc.d/init.d/functions文件至/tmp/目录,用查找替换命令为/tmp/functions的每行开头为空白字符的行的行首添加一个#号
      :%s/^[[:space:]]/#&/g

vim多文件模式
vim file1 file2 file3...
next 下一个 perv 上一个 first 第一个 last 最后一个
wall 保存所有 qall 退出所有

窗口分割模式
vim -o|-O file1 file2...
-o 水平分割
-O 垂直分割
在窗口间切换 ctrl+w,arrow(箭头方向键)

单文件窗口分割
ctrl+w,s split 水平分割
ctrl+w,v vertical 垂直分割

定制vim的工作特性
配置文件 永久有效
全局 /etc/vimic
个人 ~/.vimrc 需要手动创建
末行模式 当前vim进程有效

1、行号
显示 set number 简写为 set nu
取消显示 set nonumber 简写为 set nonu
2、括号匹配
匹配 set showmatch 简写为set sm
取消匹配 set noshowmatch 简写为set nosm
3、自动缩进
启用 set ai 禁用 set noai
4、高亮搜索
启用 set hlsearch 禁用 set nohlsearch
5、语法高亮
启用 syntax on 禁用 syntax off
6、忽略字符的大小写
启用 set ic 禁用 set noic

获取帮助 help (help subject)

练习br/>1、复制/etc/rc.d/init.d/functions文件至/tmp目录,替换/tmp/functions文件中的/etc/sysconfig/init为/var/log;
:%s@/etc/sysconfig/init@/var/log@g
2、删除/tmp/functions文件中所有以#开头,且#后面至少有一个空白字符的行的行首的#号;
:%s@#([[:space:]]+)@\1@g

bash条件测试
测试方式
test expression
[ expression ]
[[ expression ]]

测试表达式的类别
数值比较 字符串测试 文件测试

文件测试
存在性测试
-a file 文件是否存在
[root@localhost ~]# test -a /etc/passwd
[root@localhost ~]# echo $?
0

-e file 文件存在性测试,存在为真,否则为假
[root@localhost ~]# test -e /etc/passwd
[root@localhost ~]# echo $?
0

存在性及类别测试
-b file 是否存在且为块设备文件
[root@localhost ~]# test -b /dev/sda
[root@localhost ~]# echo $?
0

-c file 是否存在且为字符设备文件
[root@localhost ~]# test -c /dev/tty
[root@localhost ~]# echo $?
0

-d file 是否存在且为目录文件
[root@localhost ~]# test -d /dev
[root@localhost ~]# echo $?
0

-f file 是否存在且为普通文件
[root@localhost ~]# test -f /etc/passwd
[root@localhost ~]# echo $?
0

-h file 或 -L file 是否存在且为符号链接文件
[root@localhost ~]# test -h /etc/system-release
[root@localhost ~]# echo $?
0
[root@localhost ~]# test -L /etc/system-release
[root@localhost ~]# echo $?
0

-p file 是否存在且为命名管道文件
[root@localhost ~]# test -p /var/spool/postfix/public/qmgr
[root@localhost ~]# echo $?
0

-S file 是否存在且为套接字文件
[root@localhost ~]# test -S /dev/log
[root@localhost ~]# echo $?
0

文件权限测试
-r file 是否存在且可读
[root@localhost ~]# test -r /etc/passwd
[root@localhost ~]# echo $?
0

-w file 是否存在且可写
[root@localhost ~]# test -w /etc/passwd
[root@localhost ~]# echo $?
0

-x file 是否存在且可执行
[root@localhost ~]# test -x /tmp/a.sh
[root@localhost ~]# echo $?
0

文件特殊权限测试
-g file 是否存在且拥有sgid权限
[root@localhost ~]# test -g /tmp
[root@localhost ~]# echo $?
0

-u file 是否存在且拥有suid权限
[root@localhost ~]# test -u /tmp
[root@localhost ~]# echo $?
0

-k file 是否存在且拥有sticky权限
[root@localhost ~]# test -k /tmp
[root@localhost ~]# echo $?
0

文件大小测试
-s file 是否存在且非空
[root@localhost ~]# test -s /etc/passwd
[root@localhost ~]# echo $?
0

文件是否打开
-t fd fd表示文件描述符是否已经打开且与某终端相关

-N file 文件自从上一次被读取之后是否被修改过
[root@localhost ~]# test -N /etc/passwd
[root@localhost ~]# echo $?
1

-O file 当前有效用户是否为文件属主
[root@localhost ~]# test -O /etc/passwd
[root@localhost ~]# echo $?
0

-G file 当前有效用于是否为文件属组
[root@localhost ~]# test -G /etc/passwd
[root@localhost ~]# echo $?
0

双目测试
file1 -ef file2 file1与file2 是否指向同一个设备上的相同的inode
[root@localhost ~]# test /etc/passwd -ef /tmp/passwd
[root@localhost ~]# echo $?
1

file1 -nt file2 file1是否新于file2
[root@localhost ~]# test /etc/passwd -nt /tmp/passwd
[root@localhost ~]# echo $?
1

file1 -ot file2 file1是否旧于file2
[root@localhost ~]# test /etc/passwd -ot /tmp/passwd
[root@localhost ~]# echo $?
0

组合测试条件
逻辑运算
第一种方式
command1 && command2
[root@localhost ~]# test -e /etc/passwd && test -r /etc/passwd
[root@localhost ~]# echo $?
0

command1 || command2
[root@localhost ~]# test -e /etc/passwd || test -x /etc/passwd
[root@localhost ~]# echo $?
0

! command
[root@localhost ~]# ! test -e /etc/passwd
[root@localhost ~]# echo $?
1

[ -e file ] && [ -r file ]

第二种方式
expression1 -a expression2
[root@localhost ~]# [ -e /etc/passwd -a -r /etc/passwd ]
[root@localhost ~]# echo $?
0

expression1 -o expression2
[root@localhost ~]# [ -e /etc/passwd -o -x /etc/passwd ]
[root@localhost ~]# echo $?
0

! expression
[root@localhost ~]# [ ! -e /etc/passwd ]
[root@localhost ~]# echo $?
1

必须使用测试命令进行

[ -z "$hostname" -o "$hostname"=="localhost.localdomain" ] && hostname www.abc.com
[ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab

猜你喜欢

转载自blog.51cto.com/3832598/2114855