当前位置:首页 > 芯闻号 > 充电吧
[导读]单引 双引 反引用[] [[]]将命令的输出读入一个变量中,可以将它放入双引号中,即可保留空格和换行符(\n)out=$(cat text.txt)输出1 2 3out="$(cat text.txt

单引 双引 反引用[] [[]]

将命令的输出读入一个变量中,可以将它放入双引号中,即可保留空格和换行符(n)

out=$(cat text.txt)

输出1 2 3


out="$(cat text.txt)"

输出:

1

2

3



--------------[]一般用于算术比较


-gt 大于

-lt 小于

-ge 大于等于

-le 小于等于


逻辑与-a

[ $var1 -eq 0 -a $var2 -gt 2 ]


逻辑或

[ $var1 -eq 0 -o $var2 -gt 2 ]


[ condition ] && action 等价于if...fi



if [ "$LOOK_OUT" -gt "85" ]



if [ -e /home/slynux ]; then

...

fi


-----------------[[]]一般用于字符串比较



if [[ -n $str1 ]] && [[ -z $str2 ]] ;

then

commands;

fi








========================


1、字符串判断

str1 = str2      当两个串有相同内容、长度时为真
str1 != str2      当串str1和str2不等时为真
-n str1        当串的长度大于0时为真(串非空) if [[ -n $1 ]]
-z str1        当串的长度为0时为真(空串)
str1         当串str1为非空时为真

2、数字的判断

int1 -eq int2    两数相等为真
int1 -ne int2    两数不等为真
int1 -gt int2    int1大于int2为真
int1 -ge int2    int1大于等于int2为真
int1 -lt int2    int1小于int2为真
int1 -le int2    int1小于等于int2为真

3 目录文件的判断(if [ ])

-r file     用户可读为真
-w file     用户可写为真
-x file     用户可执行为真
-f file     文件为正规文件为真
-d file     文件为目录为真
-c file     文件为字符特殊文件为真
-b file     文件为块特殊文件为真
-s file     文件大小非0时为真
-t file     当文件描述符(默认为1)指定的设备为终端时为真

3、复杂逻辑判断

-a         与
-o        或
!        非

下面是一些使用实例:

#!/bin/sh
myPath="/var/log/httpd/"
myFile="/var /log/httpd/access.log"

#这里的-x 参数判断$myPath是否存在并且是否具有可执行权限
if [ ! -x "$myPath"]; then
mkdir "$myPath"
fi

#这里的-d 参数判断$myPath是否存在
if [ ! -d "$myPath"]; then
mkdir "$myPath"
fi

#这里的-f参数判断$myFile是否存在
if [ ! -f "$myFile" ]; then
touch "$myFile"
fi

#其他参数还有-n,-n是判断一个变量是否是否有值
if [ ! -n "$myVar" ]; then
echo "$myVar is empty"
exit 0
fi

#两个变量判断是否相等
if [ "$var1" == "$var2" ]; then
echo '$var1 eq $var2'
else
echo '$var1 not eq $var2'
fi



-----------------获取名称.扩展名


file_jpg="sample.jpg"

name=${file_jpg%.*}

输出sample



file_jpg="sample.jpg"

extension=${file_jpg#*.}

输出jpg



------------------ time 计算命令执行时间


time command


--------------- 重定向

0 stdin标准输入

1 stdout标准输出   

2 stderr标准错误


文件打开模式:

> 等同于1> 截断模式

>>等同于1>> 追加模式

<用于从文件中读取至stdin 只读模式




ls + 2> out.txt

stdout不会有任何输出,因为错误已经重定向到out.txt中了




可以将stderr单独重定向到一个文件,将stdout重定向到另一个文件:

cmd 2>stderr.txt 1>stdout.txt



将stderr转换成stdout,使得stderr和stdout都被重定向到同一个文件:

cmd 2>&1 output.txt

或者

cmd &> output.txt


将stderr输出丢弃

some_command 2> /dev/null


将文件重定向到命令

cmd < file


向log文件中写入头部数据

#!/bin/bash

cat <

LOG FILE HEADER

this is a test log file

EOF



-----------------------/dev/null 2>&1



*/1 * * * * root /usr/local/php/bin/php /var/w.php > /dev/null 2>&1



crontab内容:50 18 5-30 * * /script/myscript.sh 1> /dev/null 2>&1
其中 1> /dev/null 2>&1是什么意思??
dev/null 为系统垃圾箱
&为后台运行
但是 myscript 后面的1 和 /null后面的2 还有 &后面的1是什么意思?
1代表标准输出,2代表错误信息输出.
1>/dev/null 就是指将标准输出定向到空设备,
2>&1,的意思是将错误输出定向到和1一样的输出设备,也同样是空.



换句话说,就是不显示该程序执行过程中的任何信息


cmd >a 2>a 和 cmd >a 2>&1 为什么不同?
cmd >a 2>a :stdout和stderr都直接送往文件 a ,a文件会被打开两遍 ,由此导致stdout和stderr互相覆盖。
cmd >a 2>&1 :stdout直接送往文件a ,stderr是继承了FD1的管道之后,再被送往文件a 。a文件只被打开一遍,就是FD1将其打开
他们的不同点在于:
cmd >a 2>a 相当于使用了FD1、FD2两个互相竞争使用文件 a 的管道;
而cmd >a 2>&1 只使用了一个管道FD1, 但已经包括了stdout和stderr。
从IO效率上来讲,cmd >a 2>&1的效率更高。



----------------- 算数运算 let expr


let 可以直接执行基本的算数操作


no1=4

no2=5

let result=no1+no2

echo $result


let no1++

let no1+=6


操作符[] ,expr 和let命令类似

result=$[ no1 + no2 ]

result=$[ $no1 + $no2 ]

result=`expr 3 + 4`

result=$(expr $no1 + 5)



---------------- 浮点运算 bc


#echo "4 * 0.56" | bc

2.24


-----------------获得字符串长度


var=123456

echo ${#var}






-----------------环境变量$PATH和export


echo $PATH

PATH通常定义在/etc/environment或/etc/profile或~/.bashrc中


export命令用来设置环境变量;


添加新的路径:

export PATH="$PATH:/home/user/bin"


或者

PATH="$PATH:/home/user/bin"

export PATH



其它环境变量:HOME,PWD,USER,UID,SHELL



查看进程相关的环境变量:

cat /proc/$PID/environ



----------------- printf 格式化输出


printf "%-5s %-10s %-4sn" No Name Mark

printf "%-5s %-10s %-4.2fn" 1 James 91.32



输出为:

No Name Mark

1 James 91.32



%-5s 指明了一个格式为左对齐且宽度为5的字符串替代(- 表示左对齐)

-4.2f 表示对浮点数的处理格式




-------------- 读取命令返回值$?


cmd;

echo $?;



-------------------------shell 调试



#!/bin/bash -xv 不用任何其他选项就可以启用调试功能了



sh -n sh16.sh 不执行script,仅查询语法

sh -x sh16.sh 将script执行过程全部列出来


需要给变量赋值时,可以这么写: 
变量名=值 
要取用一个变量的值,只需在变量名前面加一个$

a="hello world"
echo "A is:" $a



//if 注意空格

a=$1

if [[ $a -eq 2 ]] ;then

echo "1"

else

echo "2"

fi


if [[ $a = gjslint ]] ;then

echo "1"

exit 0

else

echo "2"

fi

exit 0





===================== 调用php的sh



#!/bin/bash


if [[ $0 = /* ]]

then

  curfile="$0"

else 

  curfile="$PWD/${0#./}"

fi

#得到curfile 为/usr/local/shell/automation/autoupdate_host.sh


php_path=`dirname $curfile`

#得到php_path为/usr/local/shell/automation



PHP="/usr/local/php/bin/php -q "

PROGRAM="${php_path}/clear_his.php"


#echo $PHP $PROGRAM &

$PHP $PROGRAM &


====================== [和[[有什么不同



$ type [
[ is a shell builtin
$ type [[
[[ is a shell keyword

也就是说[处理里面的字串是当作参数来处理的,而[[对待其中的字串是当作表达式来处理的
那么当作参数和表达式有什么不同呢?

表达式中不会有wordsplitting 或者glob expansion,而参数处理会有

$ ls
file file 1 #注意是2个文件(file 和file 1)
$ (foo="file 1";[[ -f $foo ]]&&echo "$foo is a file")
file 1 is a file

]$ (foo="file 1";[ -f $foo ]&&echo "$foo is a file") # 这里file 1被分成2个word,所以出错
bash: [: file: binary operator expected

再来看看glob expansion

$ touch '*'
$ (foo="*";[ -f $foo ]&&echo "$foo is a file") #为什么显示too many arguments,因为 *被扩展为所有目录下的文件
bash: [: too many arguments
$ (foo="*";[[ -f $foo ]]&&echo "$foo is a file") # *被当成普通字符了
* is a file

参数传递中




================ shell判断文件是否存在

shell判断文件,目录是否存在或者具有权限
#!/bin/sh

myPath="/var/log/httpd/"
myFile="/var /log/httpd/access.log"


# 这里的-x 参数判断$myPath是否存在并且是否具有可执行权限
if [ ! -x "$myPath"]; then
mkdir "$myPath"
fi

# 这里的-d 参数判断$myPath是否存在
if [ ! -d "$myPath"]; then
mkdir "$myPath"
fi

# 这里的-f参数判断$myFile是否存在
if [ ! -f "$myFile" ]; then
touch "$myFile"
fi

# 其他参数还有-n,-n是判断一个变量是否是否有值
if [ ! -n "$myVar" ]; then
echo "$myVar is empty"
exit 0
fi

# 两个变量判断是否相等
if [ "$var1" = "$var2" ]; then
echo '$var1 eq $var2'
else
echo '$var1 not eq $var2'
fi

-f 和-e的区别
Conditional Logic on Files

-a file exists.
-b file exists and is a block special file.
-c file exists and is a character special file.
-d file exists and is a directory.
-e file exists (just the same as -a).
-f file exists and is a regular file.
-g file exists and has its setgid(2) bit set.
-G file exists and has the same group ID as this process.
-k file exists and has its sticky bit set.
-L file exists and is a symbolic link.
-n string length is not zero.
-o Named option is set on.
-O file exists and is owned by the user ID of this process.
-p file exists and is a first in, first out (FIFO) special file or named pipe.
-r file exists and is readable by the current process.
-s file exists and has a size greater than zero.
-S file exists and is a socket.
-t file descriptor number fildes is open and associated with aterminal device.
-u file exists and has its setuid(2) bit set.
-w file exists and is writable by the current process.
-x file exists and is executable by the current process.
-z string length is zero.


==================bash中的特殊符号


* 万用字符,代表一个或多个字符(或数字)

? 万用字符,代表一个字母

# 批注,这个最常被使用在 script 当中,视为说明!

跳脱符号,将『特殊字符或万用字符』还原成一般字符

| 分隔两个管线命令的界定;

; 连续性命令的界定(注意!与管线命令并不相同)

~ 使用者的家目录

$ 亦即是变量之前需要加的变量取代值

& 将指令变成背景下工作

! 逻辑运算意义上的『非』 not 的意思!

/ 路径分隔的符号

>, >> 输出导向,分别是『取代』与『累加』

' 单引号,不具有变量置换的功能

" 具有变量置换的功能!

` ` 两个『 ` 』中间为可以先执行的指令!

( ) 在中间为子 shell 的起始与结束

[ ] 在中间为字符的组合

{ } 在中间为命令区块的组合!





exit 1:退出整个程序





--------------------dirname


dirname /home/bin/abc
得到/home/bin



------------------------- 循环读取每行 :
all_corp=sql.txt
cat $all_corp | while read line
do
echo $line
done


-----------------------整数比较

-eq 等于,如:if [ "$a" -eq "$b" ]
-ne 不等于,如:if [ "$a" -ne "$b" ]
-gt 大于,如:if [ "$a" -gt "$b" ]
-ge 大于等于,如:if [ "$a" -ge "$b" ]
-lt 小于,如:if [ "$a" -lt "$b" ]
-le 小于等于,如:if [ "$a" -le "$b" ]



if [ $counter -gt 1 ]; then

...

fi



< 小于(需要双括号),如:(("$a" < "$b"))
<= 小于等于(需要双括号),如:(("$a" <= "$b"))
> 大于(需要双括号),如:(("$a" > "$b"))
>= 大于等于(需要双括号),如:(("$a" >= "$b"))

---------------------------字符串比较
= 等于,如:if [ "$a" = "$b" ]
== 等于,如:if [ "$a" == "$b" ],与=等价
注意:==的功能在[[]]和[]中的行为是不同的,如下:
1 [[ $a == z* ]] # 如果$a以"z"开头(模式匹配 )那么将为true
2 [ $a == "z*" ] # 如果$a等于z*(字符匹配 ),那么结果为true
3
4 [ $a == z* ] # File globbing 和word splitting将会发生
5 [ "$a" == "z*" ] # 如果$a等于z*(字符匹配),那么结果为true
一点解释,关于File globbing是一种关于文件的速记法,比如"*.c"就是,再如~也是.
但是file globbing并不是严格的正则表达式,虽然绝大多数情况下结构比较像.
!= 不等于,如:if [ "$a" != "$b" ]
这个操作符将在[[]]结构中使用模式匹配.
< 小于,在ASCII字母顺序下.如:
if [[ "$a" < "$b" ]]
if [ "$a" < "$b" ]
注意:在[]结构中"<"需要被转义.
> 大于,在ASCII字母顺序下.如:
if [[ "$a" > "$b" ]]
if [ "$a" > "$b" ]
注意:在[]结构中">"需要被转义.
具体参考Example 26-11来查看这个操作符应用的例子.
-z 字符串为"null".就是长度为0.
-n 字符串不为"null"
注意:
使用-n在[]结构中测试必须要用""把变量引起来.使用一个未被""的字符串来使用! -z
或者就是未用""引用的字符串本身,放到[]结构中。虽然一般情况下可
以工作,但这是不安全的.习惯于使用""来测试字符串是一种好习惯.

awk '{print $2}' class.txt | grep '^[0-9.]' > res



iptables 配置文件目录 /etc/sysconfig/iptables

1.别名 alias,存放位置 $HOME/.bashrc
alias ll='ls -lh'
2.print=helloworld echo ${print}
3.变量:内存中一块存储单元
本地变量:登陆登出生命周期内有效,只限制于本用户
变量名=变量值
set 查看
LOCAL="TEST"
echo $LOCAL
设置变量名为只读,不能在更改,同是也不能在恢复:readonly 变量名,不能删除。

环境变量:系统变量,用于所有用户,只有环境变量才能用于所有的子进程中,本地变量不可以。
存放于/etc/profile .bash_profile
export 变量名=变量值
env或者export查看
unset 变量名 删除

变量替换:用变量的值替换变量的名
print=helloworld
echo ${print}
echo ${file1}+${file2}

--------------------位置变量:$0 $1...$9
$0:脚本的名字
$1:脚本的第一变量
$2:脚本的第二变量
向脚本中使用位置参数:./test.sh a b c

向系统命令传递参数
find /root/ -name $1 -print
./test.sh aa

标准变量:bash默认的,可以在/etc/profile中定义
EXINIT
HOME
IFS:设置分隔符,默认为空格 IFS=":"SHE
LOGNAME
MAIL 默认邮箱位置
MAILPATH多个邮箱时可以设置
TERM 显示终端类型
PS1 当前shell目录格式PS1="WANGJIAN:"
ps2 >
pwd显示当前路径 SHELL 显示当前shell
MANPATH TERMINFO



----------------------------------------------------------特殊变量
$# 变量的个数 $* 显示脚本全部参数(参数列表)

$$脚本运行的当前id号
$?显示前一个命令的运行状态

$!后台运行的最后一个进程id号
#!/bin/bash
echo "tesh.sh"
echo "this is first variable locate:$1"
echo "this is second variable locate:$2"
echo "this is third variable locate:$3"
shift
echo "count:$#"
echo "all list:$*"
echo "pid:$$"
echo "status:$?"

./tesh.sh a b c

declare :设置或显示变量 -f只显示函数名
export:创建环境变量 -p显示所有环境变量
readonly:设置只读变量,不能修改删除
unset:取消变量的定义。-f 删除只读变量
shift:输入的位置变量改变位置 shift 表位置上移一个位置,shift 2 表上移动两个位置
双引号"":引用字符或字符串除$ `
单引号'':直接引用为字符或字符串
反引号``: 作为系统命令执行 echo `echo wangjian` wangjian
反斜杆:转义特殊字符($*?)为普通字符
运算符:~取反 << >>移位 &与(同1为1,否0) |或(有1为1,全0为0) ^异或 逻辑运算符号&& ||
运用运算符:$[]:表示对其中的表达式求值 echo $[2+8] echo $[3&4] $[]等价于(())
[base#n] n(base>n)表示基数从2到36的任何基数 echo [10#8+1] 结果为9
let a+=3 a=a+3
表达式优先级别[] *= || && | ^ & ==
shell 的输入与输出
echo
-e 解析转义字符 echo -e "this is a bag nnn"
-n 回车不换行,默认换行 echo -n "this is a cat"
转义字符(c回车不换行 f禁止 t跳格相当tab n回车换行)

read:可以从键盘或文件的某一行文本中读入信息,并将其赋给一个变量。
read varible1 varible2
如果只指定了一个变量,那么read将会把所有的输入赋给改变量,直至遇到文件结束或回车。如果多个变量,就依次赋给。shell用空格作为变量之间的分隔符。
echo -n "first name:"
read firstname
echo -n "last name:"
read lastname
echo -e "your first name :${firstname}n"
echo -e "your last name :${lastname}n "

read -t 5 variable 5秒钟超时
read -p "Please enter your Username: " user -p prompt 提示语
[root@ceshiji ~]#Please enter your Username:

read -s -p "Please enter your Password: " pass -s charaters are not echoed. 字符不回显示。指输入之后,不在回显




cat:显示文件内容,创建文件,还可以用它来显示控制字符
cat file1 file2 file3 同时显示
cat file1 file2 file3>myfile
cat -v dos.txt (-v 显示控制符)

管道|:一个命令的输出传给一个命令的输入
df -k|awk '{print $1}'|grep -v 'Filesystem'

tee:把输出的一个副本输送到标准输出,另一个副本拷贝到相应的文件中。
tee files 在看见输出的同时,也将其存入一个文件。一般用于管道之后。
tee -a files 追加到files中 (-a 表追加)
who|tee who.out

标准输入 0
标准输出 1
标准错误 2

重定向:改变程序运行的输入来源和输出来源。
> >> < <<
command>>filename 2>&1
command



if语句必须以单词fi终止

if $x=sedsrc;then
echo
then
echo
fi

if [ "10" -lt "12" ]

man test

echo -n "enter your name:"
read NAME
if [ "$NAME" == ""];
then
echo "you did not enter any information"
else
echo "your name is $NAME"
fi

if cp myfile.bak myfile;
then
echo "GOOD COPY"
else
echo "basename $0 :error could not copy the files" >&2

case:多选择语句。如果匹配成功,执行匹配的命令

case 值 in
模式1)
命令1
;;
模式2)
命令2
;;
esac
*表任意字符,?表任意单字符 []表范围

echo -n "enter a number from 1 to 3;"
read ANS
case $ANS in
1)
echo "you select 1"
;;
2)
echo "you select 2"
;;
3)
echo "you select 3"
;;
*)
echo "basename $0 :this is not between 1 and 3" >&2
;;
esac


case $1 in
get|GET)
create_dir
get_config_file
;;
put|PUT)
put_config_file
;;
stop|STOP)
stop_server
;;
start|START)
start_server
;;
restart|RESTART)
restart_server
;;
*)
echo
echo "$Color_err Useage: ./Configure_squid.sh get|put|stop|start|restart $Color_end"
echo
exit 1
;;
esac



for
for 变量 in 列表
do
命令1
命令2
done
for语句 :提供循环执行
使用格式:
for var in values #var是变量 values是一组值
do
语句 #可以是多条语句
done
注意values的值可以全部列出,也可是通配的方式,也可以是某命令的输出值(如$(ls))。
values的值可以是:
1.列表 in 1 2 3 4 5 用空格隔开
2.文件 in file1 file2 file3
3.变量 in $a 命令输出赋值
4.命令 in `ls abc*`
5.字符串表 in "orange red blue gray"
5.特殊: 有时没有in 此时将命令行参数传入
for loop
do
find / -name $loop -print
done

[root@localhost ~]# ./sh match
/root/match
[root@localhost ~]# cat sh
#!/bin/bash
for loop
do
find /root -name $loop -print
done

#!/bin/sh
for ((i = 1; i < 254; i++)) #必须用两个括号
do
arping -I eth0 60.191.82.$i -c 1
done
arp -a > mac_table



当变量值在列表里,for循环即执行一次所有命令,使用变量名访问列表中的取值。命令可为任何有效的shell命令和语句。变量名为任意单词。in列表用法是可选的,如果不用它,for循环使用命令行的位置参数。in列表可以包含替换、字符串和文件名。
for((i=1;i<=10;i=i+1))
do
touch ar_$i;
touch full_$i;
done;

for i in {1..100}
do
.......
done

#!/bin/sh
for i in `seq 1 100`
do
echo $i
done

for loop in 1 2 3 4
do
echo $loop
done

for loop in "orange red blue grey"
do
echo $loop
done

for i in $(ls); do du -sh $i; done | sort -n 查看当前目录的大小按小--大排列


until 条件
do
命令1
命令2
...
done
条件可为任意测试条件,测试发生在循环末尾,因此循环至少执行一次.
read look
until [ "$look" ]
do
echo "full"
done

sleep 1
nohup ./test.sh &

while 命令
do
命令1
命令2
...
done

$ cat "filelist.txt"
name.txt□
txtf
□a□b□c□
$ while read file; do echo "$file"; done < "filelist.txt"
name.txt
txtf
a□b□c



echo "press ctrl+d ,stop"
while echo -n "enter a file for you like:" ; read film
do
echo " Yeah ,${file} is a good film "
done

while read line
do
echo $line
done<name.txt

break [n]:跳出循环,如果是在一个嵌入循环里,可以指定n来跳出的循环个数
continue:跳过循环步骤(本次循环)

continue只能跳过本次循环。

while :

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

默认状态下,FTP 站点允许匿名访问,FTP 服务器接受对该资源的所有请求,并且不提示用户输入用户名或密码。如果站点中存储有重要的或敏感的信息,只允许授权用户访问,应禁止匿名访问。

关键字: FTP 匿名 unix

Linux是一种非常流行的技术,但是对于许多对Linux不太了解的初学者,他们很好奇Linux为何受欢迎。 您会学习Linux吗?

关键字: Linux posix unix

首先我们要知道什么是UNIX系统,它是一个分时系统。最早的UNIX系统于1970年问世。此前,只有面向批处理作业的操作系统,这样的系统对于需要立即得到响应的用户来说是太慢了。

关键字: unix Linux 操作系统

  linux下的进程通信手段基本上是从Unix平台上的进程通信手段继承而来的。而对Unix发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心

关键字: Linux unix bsd

毫不夸张地说Unix是操作系统的鼻祖, Linux可以说是Unix下的创新发展。 他们有很多共同点,但也有很多不同的地方。 1. Unix和Linux的历史渊源。 Unix和Linux系统是个人爱好,但是时代不同。 ①U...

关键字: CPU Linux unix

保护网站托管环境的安全性是系统安全性的重要组成部分。在前面的六篇文章中,我们介绍了系统安全性模型:Linux安全性(Linux更常见,并且与Unix书中的Unix类似),Windows安全性,基础结构服务,虚拟机和云。计...

关键字: Linux unix Windows

就目前而言,Unix和Linux的概念模糊不清,有的人说差不多到底这两者之间有什么异同点,下面我们来分析一下。

关键字: Linux unix

毫不夸张地说Unix是操作系统的起源,Linux在Unix下可以看作是创新的。 他们有很多共同点,也有很多不同之处。 1. Unix和Linux的历史渊源Unix和Linux的系统都是基于个人兴趣和爱好的,但是时间有所不...

关键字: freebsd Linux unix

Linux一开始就不是为桌面用户准备的,林纳斯自己本身就是一个Unix极客,他设计Linux就参考了Unix的设计哲学,也就是说Linux从一开始就是为专业用户设计的。

关键字: Linux unix 桌面系统

FreeBSD 11.4 已经发布,这是 stable/11 分支的第五个也是最后一个版本。FreeBSD 是一种自由类 Unix 操作系统,是由经过 BSD、386BSD 和 4.4BSD 发展而

关键字: freebsd unix
关闭
关闭