Shell简单入门
Shell 既指代一门解释性脚本语言,又指代一个程序(外部命令解析器),Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 这个程序为用户提供GUI(终端)/命令行界面并可通过这2个界面直接访问操作系统内核的服务。
需要注意的是:常说的 shell 通常都是指 shell 脚本,但要分清,shell 和 shell script 是两个不同的概念。
由于习惯的原因,简洁起见, “shell编程” 都是指 shell 脚本编程,不是指开发 shell 脚本命令解释器。
常见shell脚本解释器
- Bourne Shell(/bin/sh或/usr/bin/sh)
- Bourne Again Shell(/bin/bash)
- C Shell(/usr/bin/csh)
- K Shell(/usr/bin/ksh)
- Shell for Root(/sbin/sh)
验证默认B A Shell 脚本解释器:echo $SHELL
结果应为:/bin/bash
为什么使用BAShell,因为免费好用,BAShell 在日常工作中被广泛使用,同时也是大多数 Linux 系统默认 Shell 解释器
shell 脚本文件后缀:.sh
#!/bin/bash
#指定shell脚本的解析器
Quick Start
#1.shell脚本 作为解释器参数
#2.shell脚本 作为可执行程序
[root@inbreeze ~]# vim hello.sh
echo "hello word"
# 1.1使用B Shell脚本解释器 执行sh文件
[root@inbreeze ~]# sh hello.sh
hello word
# 1.2使用B A Shell脚本解释器 执行sh文件
[root@inbreeze ~]# bash /root/hello.sh
hello word
[root@inbreeze ~]# ll
...
-rw-r--r--. 1 root root 18 Sep 20 09:15 hello.sh
[root@inbreeze ~]# chmod 777 hello.sh
# 2.1直接执行sh文件(需要执行权限),使用默认的shell解释器,相对路径
[root@inbreeze ~]# ./hello.sh
hello word
# 2.2直接执行sh文件,使用默认的shell解释器,绝对路径
[root@inbreeze ~]# /root/hello.sh
hello word
Second Start
[root@inbreeze ~]# vim second.sh
#!/bin/bash
cd /root/
touch banzhang.txt
echo "i am Superman" >> banzhang.txt
[root@inbreeze ~]# chmod 777 second.sh
[root@inbreeze ~]# ./second.sh
[root@inbreeze ~]# cat banzhang.txt
i am Superman
脚本变量
系统变量
常用系统变量:
H
O
M
E
、
HOME、
HOME、PATH、
P
W
D
、
PWD、
PWD、SHELL、
U
S
E
R
注
:
USER 注:
USER注:HOME–当前用户Home目录路径,所有系统变量区分大小写
注:查询所有系统变量set
自定义变量
规则:字母数字下划线,不能以数字开头。
作用范围:当前的连接会话Session,在当前会话运行其他shell脚本也获取不到。
语法:
1.定义/重赋值:变量名=值
,等号左右无空格,变量值有空格使用""
括起,默认值类型都是字符串
2.撤销:unset 变量名
3.静态变量:readonly 变量名=值
,无法重赋值、撤销
4.输出至shell:echo $A
5.提升session局部变量为全局变量:export $a
特殊变量
$n
功能:可用于传递参数
规则:$0代表当前文件名称 或 前面 | 传入的全部数据,
1
−
9
代
表
∗
∗
传
递
的
参
数
∗
∗
或
∗
∗
分
割
后
的
列
数
据
∗
∗
如
果
10
以
上
,
使
用
1-9代表**传递的参数** 或 **分割后的列数据** 如果10以上,使用
1−9代表∗∗传递的参数∗∗或∗∗分割后的列数据∗∗如果10以上,使用{10}
实例:
[root@inbreeze ~]# vim parameter.sh
echo $0 $1 "$2"
[root@inbreeze ~]# chmod 777 parameter.sh
[root@inbreeze ~]# ./parameter.sh aaa bbb
./parameter.sh aaa bbb
KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲ 功能:存储传入参数的数量 规…#,直接使用
$*
@
功
能
:
获
取
命
令
行
传
入
的
所
有
参
数
区
别
:
加
上
‘
"
"
‘
后
,
‘
"
@ 功能:获取命令行传入的所有参数 区别:加上`""`后,`"
@功能:获取命令行传入的所有参数区别:加上‘""‘后,‘"*"把所有参数看成一个变量,
"$@"`把每个参数当作独立变量
$?
功能:查看上一个脚本的执行情况
规则:非0 失败,0 正常执行。
数值运算符
基本语法
1.使用 $(())
2.使用 $[]
3.使用 expr +,-,\*,/,%
,注意 expr 的运算符间需要有空格
实例:
[root@inbreeze ~]# expr `expr 3 + 2` \* 5
[root@inbreeze ~]# echo $(((3+2)*5))
[root@inbreeze ~]# echo $[(3+2)*5]
条件判断
基本语法:[ condition ]
,注意 condition 前后必须有空格
规则:condition 非空即为 true,比如 condition 为一个字符/字符串就判断为 true,[ ] 空判断为 false
常用判断条件:
1.两个整数之间的比较【必须是整数,浮点数都不可以】6
#!/bin/bash
# 关系运算符*6:
# 小于 -lt,小于等于 -le,等于 -eq,不等于 -ne,大于 -gt,大于等于 -ge
# 关系运算符只支持数字,不支持字符串,除非字符串的值是数字
# 语法:[ int1 -选项 int2 ]
a=10
b=20
[ $a -lt $b ]
[ $a -le $b ]
[ $a -eq $b ]
[ $a -ne $b ]
[ $a -gt $b ]
[ $a -ge $b ]
2.两个字符/字符串之间的比较 5
#!/bin/bash
# 字符串运算符*5:
# 等于 = ,不等于 != ,长度为0true -z ,长度不为0true -n ,不是空串true $
# 语法:[ "" -选项 "" ]
a="abc"
b="efg"
[ $a = $b ]
[ $a != $b ]
[ -z $a ]
[ -n "$a" ] # 与$a相同,shell对字符串""内的"$"进行特殊处理
[ $a ]
3.两个变量之间比较 5
#!/bin/bash
# != 不等 ,== 等于
# 语法:[ $var != / == $var ]
a=10
b=20
if [ $a != $b ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a == $b: a 等于 b"
fi
# 布尔运算符*3:
# ! 非运算,-o 或运算,-a 与运算
if [ $a -lt 100 -a $b -gt 15 ]
then
echo "$a 小于 100 且 $b 大于 15 : 返回 true"
else
echo "$a 小于 100 且 $b 大于 15 : 返回 false"
fi
# 逻辑运算符*2:
# || 逻辑或,&& 逻辑与
a=10
b=20
if [[ $a -lt 100 && $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
4.文件判断
#!/bin/bash
# 文件测试运算符
# -r 有读权限 -w 有写权限 -x 有执行权限,-f 普通文件 -d 目录 -b 块设备 -c 字符设备
# -s 文件不为空,-e 文件目录存在
# 语法:[ -选项 filePath ]
file="/root/test.sh"
if [ -r $file ]
then
echo "文件可读"
else
echo "文件不可读"
fi
补充实例:
# 两整数使用字符比较符 = ,必须在 = 前后加入空格,否则就是一个非空字符串
# 非空字符串 必定返回true,echo $? => 0
[root@inbreeze ~]# [ a = b ]
[root@inbreeze ~]# echo $?
1
[root@inbreeze ~]# [ a=b ]
[root@inbreeze ~]# echo $?
0
流程控制
选择分支
if elif else
语法:
# 1.1 if 写法1
if [ condition ];then
programs
fi
# 1.2 if 写法2
if [ condition ]
then
programs
fi
# 2.if else
if [ condition ]
then
programs
else
programs
fi
# 3.if elif else
if [ condition ]
then
programs
elif [condition]
programs
else
programs
fi
规则:
1.if elif 后面要有空格
2.if 开头 fi 结尾成对出现
实例:
[root@inbreeze ~]# vim ifelifelse.sh
#!/bin/bash
if [ $1 -eq 1 ]
then
echo "banzhang zzzz"
elif [ $1 -eq 2 ]
then
echo "cls zzzz"
else
echo "input error"
fi
[root@inbreeze ~]# chmod 777 ifelifelse.sh
[root@inbreeze ~]# ./ifelifelse.sh
./ifelifelse.sh: line 2: [: -eq: unary operator expected
./ifelifelse.sh: line 5: [: -eq: unary operator expected
[root@inbreeze ~]# ./ifelifelse.sh 2
cls zzzz
[root@inbreeze ~]# ./ifelifelse.sh 1
banzhang zzzz
[root@inbreeze ~]# ./ifelifelse.sh 3
input error
case
语法:
case $var in
"")
programs
;;
2)
programs
;;
*)
programs
;;
esac
规则:$var 数值,字符,字符串。java switch支持的类型—— int byte short char , 1.5 enmu , 1.7 String。
实例:
[root@inbreeze ~]# vim case.sh
#!/bin/bash
case $1 in
"a")
echo "This String"
;;
2)
echo "This number"
;;
*)
echo "This default case"
;;
esac
[root@inbreeze ~]# chmod 777 case.sh
[root@inbreeze ~]# ./case.sh 2
This number
[root@inbreeze ~]# ./case.sh 1
This default case
[root@inbreeze ~]# ./case.sh a
This String
循环
注:需要空格的地方——condition与expr
for
语法:
# 语法1 for
for (( 初始值;循环控制条件;变量变化 ))
do
programs
done
# 语法2 foreach
for 变量 in 值1 值2 值3…
do
programs
done
规则:shell没有+=
,切记在for循环里写全累加表达式。
实例:
# for 实例
[root@inbreeze ~]# vim for.sh
#!/bin/bash
s=0
for((i=1;i<=10;i++))
do
s=$[$s+$i]
done
echo $s
[root@inbreeze ~]# chmod 777 for.sh
[root@inbreeze ~]# ./for.sh
55
# foreach 实例1
[root@inbreeze ~]# vim foreach.sh
#!/bin/bash
for i in $*
do
echo "Love $i~~~"
done
echo "=================="
for i in $@
do
echo "Love $i~~~"
done
[root@inbreeze ~]# chmod 777 foreach.sh
[root@inbreeze ~]# ./foreach.sh cls hls zls
Love cls~~~
Love hls~~~
Love zls~~~
==================
Love cls~~~
Love hls~~~
Love zls~~~
# foreach 实例2
[root@inbreeze ~]# vim foreach.sh
#!/bin/bash
for i in "$*"
do
echo "Love $i~~~"
done
echo "=================="
for i in "$@"
do
echo "Love $i~~~"
done
[root@inbreeze ~]# chmod 777 foreach.sh
[root@inbreeze ~]# ./foreach.sh cls xls zls
Love cls xls zls~~~
==================
Love cls~~~
Love xls~~~
Love zls~~~
while
语法:
while [ condition ]
do
programs
done
规则:shell script 没有 i++ 计算式,只有 i++ 循环变量变化式,切记在while循环中写全条件变化表达式。
实例:
[root@inbreeze ~]# vim while.sh
#!/bin/bash
s=0
i=1
while [ $i -ne 101 ]
do
s=$[$s+$i]
i=$[$i+1]
done
echo $s
[root@inbreeze ~]# chmod 777 while.sh
[root@inbreeze ~]# ./while.sh
5050
基础函数
read()
功能:用于读取控制台的键盘输入
语法:read -t n -p ""
选项
-t n:time,时间限制
-p “”:phrase,提示语
#!/bin/bash
read -t 5 -p "在7s内输入您的姓名:" NAME
echo "欢迎 来到 上当" $NAME
basename()
功能:从路径中获取文件名,不包含后缀
语法:basename path suffix
,suffix:删除同名后缀
[root@inbreeze ~]# basename /home/atguigu/banzhang.txt
banzhang.txt
[root@inbreeze ~]# basename /home/atguigu/banzhang.txt .txt
banzhang
dirname()
功能:去除绝对路径中包含的文件名,留下目录路径
语法:dirname absolutePath
[root@inbreeze ~]# dirname /home/atguigu/banzhang.txt
/home/atguigu
自定义函数
语法:
# 声明定义
function funcName(){
Action;
[return int;]
}
# 调用
funcName
规则:
实例
[root@inbreeze ~]# vim ownfunc.sh
function sum(){
s=0
# 此处的$1 $2是 sum函数的局部变量,来自 调用sum函数传入的变量
s=$[$1+$2]
echo $s
}
read -p "First num:" num1
read -p "Second num:" num2
# 此处的$num1 $num2是命令行传入的参数,属于这个shell脚本共享的变量,同时也是传入sum函数的实参
sum $num1 $num2
[root@inbreeze ~]# chmod 777 ownfunc.sh
[root@inbreeze ~]# ./ownfunc.sh
First num:5
Second num:6
11
$重点函数
cut
功能:只负责 剪切 文件数据,并将剪切留下的结果输出。以行,列,正则表达式,分割符为工具。
语法:cut [-选项] filename
,默认分割符是 制表符 /t,cut区分空格数量
选项:
-f 列号,提取第几列,多列以,
分隔,取范围使用-
(如果是无限端 直接不写即可 3-)
-d 分割符,按照指定的分割符分割
实例
[root@inbreeze ~]# vim cut.txt
dong shen
guan zhen
wo wo
lai lai
le le
# 获取第1列(一列)
#注意:cut不会真的剪切源文件,是复制一份然后对副本剪切输出
[root@inbreeze ~]# cut cut.txt -d " " -f 1
dong
guan
wo
lai
le
[root@inbreeze ~]# cat cut.txt
dong shen
guan zhen
wo wo
lai lai
le le
# 获取2,3列(多列)
# 注意:上下都是以单个空格cut的,而 wo wo 之间有2个空格,2个空格间有一列,故共分3列
[root@inbreeze ~]# cut cut.txt -d " " -f 2,3
shen
zhen
wo
lai
le
# 获取某列某行(单元格)
# 通过grep获取行与cut获取列的组合
[root@inbreeze ~]# cut -d " " -f 1 cut.txt | grep "guan"
guan
实用场景:
1.获取 $PATH 系统环境变量的指定值
# $PATH 第2个“:”开始后的所有路径
[root@inbreeze ~]# echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
[root@inbreeze ~]# echo $PATH | cut -d ":" -f 3-
/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
2.获取当前IP地址
[root@inbreeze ~]# ifconfig
eth2 Link encap:Ethernet HWaddr 00:0C:29:A4:FD:3C
inet addr:192.168.142.122 Bcast:192.168.142.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fea4:fd3c/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:23177 errors:0 dropped:0 overruns:0 frame:0
TX packets:12948 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:27517597 (26.2 MiB) TX bytes:1105838 (1.0 MiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:58 errors:0 dropped:0 overruns:0 frame:0
TX packets:58 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:4888 (4.7 KiB) TX bytes:4888 (4.7 KiB)
[root@inbreeze ~]# ifconfig eth2
eth2 Link encap:Ethernet HWaddr 00:0C:29:A4:FD:3C
inet addr:192.168.142.122 Bcast:192.168.142.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fea4:fd3c/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:23203 errors:0 dropped:0 overruns:0 frame:0
TX packets:12963 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:27520327 (26.2 MiB) TX bytes:1109032 (1.0 MiB)
[root@inbreeze ~]# ifconfig eth2 | grep "inet addr"
inet addr:192.168.142.122 Bcast:192.168.142.255 Mask:255.255.255.0
[root@inbreeze ~]# ifconfig eth2 | grep "inet addr" | cut -d ":" -f 2
192.168.142.122 Bcast
[root@inbreeze ~]# ifconfig eth2 | grep "inet addr" | cut -d ":" -f 2 | cut -d " " -f 1
192.168.142.122
sed
是一种缓冲流编辑器,一次处理文件的一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区中的内容,完成后把缓冲区的内容送往命令行输出。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。
语法:sed [选项] 'command' file
,单引号
选项:-e,用于执行多个sed操作,每个command前 不加 -e 只执行第一个command
command:
na,第n行下插入,a后面可直接 空格字符串
nd | //d,第n行删除,正则表达式匹配删除行
s/ / /
,查找并替换
g,全部,通常跟在's/ / /'
最后一个斜杠后
实例
# 数据准备
[root@inbreeze ~]# vim sed.txt
dong shen
guan zhen
wo wo
lai lai
le le
# 单个sed操作
# 1.将“mei nv”这个单词插入到sed.txt第二行下【选项没啥用,command最有用】
[root@inbreeze ~]# sed '2a mei nv' sed.txt
dong shen
guan zhen
mei nv
wo wo
lai lai
le le
# 2.删除包含 wo 的行
[root@inbreeze ~]# sed '/wo/d' sed.txt
dong shen
guan zhen
lai lai
le le
# 3.所有的wo替换为ni
[root@inbreeze ~]# sed 's/wo/ni/g' sed.txt
dong shen
guan zhen
ni ni
lai lai
le le
# 执行多个sed操作 -e
# 1.第二行删除并将其他全部的wo替换为ni
[root@inbreeze ~]# sed -e '2d' -e 's/wo/ni/g' sed.txt
dong shen
ni ni
lai lai
le le
awk[最强]
强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。
语法:awk [选项] ‘pattern1{action1} pattern2{action2}...’ filename
pattern:表示AWK在数据中查找的内容,就是匹配模式
action:在找到匹配内容时所执行的一系列命令。常用 print
n
挑
选
显
示
行
,
p
r
i
n
t
"
"
增
加
一
行
字
符
串
,
选
项
:
−
F
指
定
文
件
分
割
符
,
−
v
声
明
并
赋
值
一
个
用
户
定
义
变
量
(
−
v
变
量
取
值
不
需
要
n 挑选显示行,print "" 增加一行字符串, 选项:-F 指定文件分割符,-v 声明并赋值一个用户定义变量(-v变量取值不需要
n挑选显示行,print""增加一行字符串,选项:−F指定文件分割符,−v声明并赋值一个用户定义变量(−v变量取值不需要符号)
内置变量:FILENAME 文件名,NR 已读取记录数/行数,NF 切割后列的总数
实例
# passwd 数据源准备
[root@inbreeze ~]# cp /etc/passwd ./
# 1.搜索passwd文件以root关键字开头的所有行,使用:切分,并输出该行的第1列和第7列,中间以,号分割
# 【使用$n 表示列】
[root@inbreeze ~]# awk -F ":" '/^root/{print $1","$7}' passwd
root,/bin/bash
# 2.对/etc/passwd用冒号切分后,只显示第一列和第七列,然后以逗号分割,
# 且在所有行前面添加列名"user,shell" 在最后一行添加"banzhang,/bin/zuishuai"。
# 【BEGIN END 在所有行数据读取之前、之后执行,print可以挑选显式行,也可以增添""字符串】
[root@inbreeze ~]# awk -F ":" '{print $1","$7} BEGIN{print "user,shell"} END{print "banzhang,/bin/zuishuai"}' passwd
user,shell
root,/bin/bash
...
tcpdump,/sbin/nologin
banzhang,/bin/zuishuai
# 3.将passwd文件中的第三列数值取出,并加1 后输出
[root@inbreeze ~]# awk -F ":" -v i=1 '{print $3+i}' passwd
1
2
3
4
...
# 4.统计使用冒号切分passwd后,文件名,每行的行号,每行的列数
[root@inbreeze ~]# awk -F ":" '{print FILENAME",row:"NR",col:"NF}' passwd
passwd,row:1,col:7
passwd,row:2,col:7
passwd,row:3,col:7
...
实用场景
# 切割IP *2 (第一种 cut)
# 区别:操作上没有区别都是调用2次函数,只是对于 行数据的最前空格的处理不同
# awk对于行数据的最前空格,采取直接忽略策略,不计算至 连续空格分割【以 数据空格数据 的格式才算第一个单空格】
# 并且,awk以空格为分割域时,是以单个或多个连续的空格为分隔符
# cut对于行数据的最前空格,采取不忽略策略,计算至 单空格分割,锱铢必较
[root@inbreeze ~]# ifconfig eth2
eth2 Link encap:Ethernet HWaddr 00:0C:29:A4:FD:3C
inet addr:192.168.142.122 Bcast:192.168.142.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fea4:fd3c/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:28232 errors:0 dropped:0 overruns:0 frame:0
TX packets:16150 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:28086021 (26.7 MiB) TX bytes:1594883 (1.5 MiB)
[root@inbreeze ~]# ifconfig eth2 | grep "inet addr"
inet addr:192.168.142.122 Bcast:192.168.142.255 Mask:255.255.255.0
[root@inbreeze ~]# ifconfig eth2 | grep "inet addr" | awk -F " " '{print $1","$2}'
inet,addr:192.168.142.122
[root@inbreeze ~]# ifconfig eth2 | grep "inet addr" | awk -F " " '{print $2}' | awk -F ":" '{print $2}'
192.168.142.122
# 查询sed.txt中空行所在的行号【使用正则表达式进行匹配】
[root@inbreeze ~]# cat sed.txt
dong shen
guan zhen
wo wo
lai lai
le le
[root@inbreeze ~]# awk '/^$/{print NR}' sed.txt
5
sort
语法:sort [-选项] [file]
选项:-n 按照数值大小排序,-r 以相反的顺序排序,-t 设置排序时所用的分割符,-k 指定以哪列排序
注意:如果不加入-n,可能会导致2位数与1位数的数值比较失序,例如,1 10 2 3 …,无 -n 只识别第一位/列的值
实例
# 数据准备
[root@inbreeze ~]# vim sort.txt
aaa:10:1.1
ccc:30:3.3
ddd:40:6.6
bbb:20:2.2
eee:50:5.5
# 1.默认排序,以第1列,类型排序【空行会被放置在最上面】
[root@inbreeze ~]# sort sort.txt
aaa:10:1.1
bbb:20:2.2
ccc:30:3.3
ddd:40:6.6
eee:50:5.5
# 2.按照:分割后的 第3列 倒序 排序
[root@inbreeze ~]# sort -k 3 -t ":" -rn sort.txt
ddd:40:6.6
eee:50:5.5
ccc:30:3.3
bbb:20:2.2
aaa:10:1.1
强记
shell script 没有+=,i++,但在系统函数传入{}中可以使用【有点EL表达式的味道】
查找空行,空值,404,500
awk '/^$/{print NR}' sed.txt
计算指定列 n 的和
cat xxx.txt | awk -F " " '{sum+=$n} END{print sum}'
判断普通文件存在
[ -f file.txt ]
追加符号 > 与 condition [ ] 与 字符串 与 数值
# 数字
# 已存在名为 23 文件,且有内容23
# 不满足[ condition ]规范,命令报错
[root@inbreeze Desktop]# [23>22]
bash: [23: command not found
[root@inbreeze Desktop]# echo $?
127
# 结果:以>追加符作为最优先执行。生成 22] 文件内容空,追加失败
# 已存在名为 23 文件,且有内容23
# 满足[ condition ]规范,命令通过
[root@inbreeze Desktop]# [ 23>22 ]
[root@inbreeze Desktop]# echo $?
1
# 结果:以>追加符作为最优先执行。生成 22 文件内容空,追加失败
# [ 23 > 22 ]同上
# 字符/字符串
# [a>b]
# 同[23>22]
[root@inbreeze Desktop]# [ a>b ]
[root@inbreeze Desktop]# echo $?
0
# 结果:以>追加符作为最优先执行。生成 b 文件
# 注意:此处的 a>b 先作为追加符执行,再被condition识别为 非空字符串故为0