基础命令
netstat命令: 用于输出和网络相关的信息,比如网络连接状况、路由表、接口统计等信息。
通过它,你可以看到有哪些网络网络连接、端口号在使用,以及哪些进程使用他们。
netstat -lntup
命令选项的说明:
选项简称 | 完整选项名 | 含义 |
---|---|---|
-a | all | 展示所有的监听和非监听的套接字 |
-t | tcp | 只展示tcp端口上的套接字 |
-u | udp | 只展示udp端口上的套接字 |
-l | listening | 只展示监听的套接字 |
-n | numeric | 以数字化的形式展示地址、端口号 |
-c | continuous | 每秒钟连续打印指定的信息 |
-p | program | 同时展示出每个套接字所属的进程的PID和名称 |
-e | extend | 展示更多的附加信息 |
lsof -i:8089查看端口
cd :切换目录
用法:cd
cd ../ 切换到上级目录
cd / 切换到根目录
cd ~ (或只有cd )切换到当前用户主目录(home底下以用户名命名的文件夹) /root目录
mkdir 创建目录
mkdir 目录名 -p 递归创建目录
2.rmdir 删除空目录
用法:rmdir 目录名
也可用:rm -rf 目录名
3.ls 查看目录或文件信息
主要选项:
-l 列出目录或者文件的详细信息。比如权限、修改时间等等
-a 列出当前目录下所有文件,包括隐藏文件(已点开头的都是隐藏文件)
4.vi 文本编辑器
键入i 进入编辑状态
退出编辑按ESC键
不保存退出: :q!
保存退出: :wq
输入/,进入搜索
输入:set nu,显示每一行的行数
按键盘G,可以直接定位到最末尾
5.cp 复制
用法:cp [选项]文件名或目录 目标地址
-R 拷贝目录及目录下所有目录和文件
cp a.txt b.txt 将a文件复制,且另命名为b文件(目录名)
6.mv 移动
用法:mv 文件名或目录 目标目录
mv a.txt ../ 将a文件移动到上级目录(将一个文件移动到另一个目录没有重命名)
mv a.txt ../b.txt 将a文件移动到上一级并改名为b文件(将一个文件移动到另一个目录并重命名)
7.rm 删除文件或目录
-f 强制删除
-r 删除目录
常用:rm -rf 文件或目录
8.find 查找文件
用法:find [路径] [选项]
常用选项有:
find . -name *.log 在当前目录查找以.log结尾的文件
find / -name log 在根目录查找log命名的目录
9.grep 过滤
在指定文件中查找字符(串)并打印该行
用法:grep 字符串 文件名
grep band file 在file文件中找寻band字符串
10.cat 显示文本文件内容
用法:cat 文件名 cat 文件名字
11.head 查看前几行
用法: head -n 5 文件名
12.tail 从指定点开始将文件写到标准输出
-n 查看行号
tail -n 5 文件名 查看后几行
tail -f error.log 不断刷新,看到最新内容
tail -n 20 error.log | grep -3 "过滤内容"
以上命令在最后 20 行中去搜索 关键字并显示关键字所在行及上下各 3 行的内容
docker logs 过滤
docker logs -f 容器名称 |grep -n -3 "过滤内容"
以上命令在所有中去搜索 关键字并显示关键字所在行及上下各 3 行的内容
13.ps 查看进程(动态)
-ef 显示所有运行进程,并显示启动进程的命令
14.netstat 查看网络状况 (net status的简写)
netstat -apn 查看所有端口
an,按一定顺序排列输出
p,表示显示哪个进程在调用
15.| 管道符 (竖线,英文输入法状态下shift+键盘上的的|\)
在命令之间建立管道,将前面命令的输出作为后面命令的输入
通过命令查找tomcat进程:ps -ef | grep tomcat
通过命令查找到占用此端口的进程编号:netstat -apn|grep 8080
16.echo 打印文件内容或编辑文件内容
常用选项有:
-n 不换行输出
-e 可以使用转义字符(\n回车,\t tab键)
示例:
echo “I am studying linux”>>xujun.txt 追加文件尾部内容
echo $? 假如返回值为0的时候,表示上一次命令成功。假如是1到255的话,则是失败
echo -e “wo\tshi\tshei”> xujun.txt
17.touch 创建一个空白文件,假如当前目录有同样的文件,则会更新文件的时间戳
-a 修改access(访问)时间
-m 修改modify(修改)时间这两个参数了解即可
文件属性
在 Linux 中我们可以使用 ll 或者 ls –l 命令来显示一个文件的属性以及文件所属的用户和组,如:
[root@www /]# ls -l
total 64
dr-xr-xr-x 2 root root 4096 Dec 14 2012 bin
dr-xr-xr-x 4 root root 4096 Apr 19 2012 boot
……
实例中,bin 文件的第一个属性用 d 表示。d 在 Linux 中代表该文件是一个目录文件。
在 Linux 中第一个字符代表这个文件是目录、文件或链接文件等等。
- 当为 d 则是目录
- 当为 - 则是文件;
- 若是 l 则表示为链接文档(link file);
- 若是 b 则表示为装置文件里面的可供储存的接口设备(可随机存取装置);
- 若是 c 则表示为装置文件里面的串行端口设备,例如键盘、鼠标(一次性读取装置)。
接下来的字符中,以三个为一组,且均为 rwx 的三个参数的组合。其中, r 代表可读(read)、 w 代表可写(write)、 x 代表可执行(execute)。 要注意的是,这三个权限的位置不会改变,如果没有权限,就会出现减号 - 而已。
Linux/Unix 的文件调用权限分为三级 : 文件所有者(Owner)、用户组(Group)、其它用户(Other Users)。
解压及压缩命令
tar压缩命令
tar -cvf examples.tar files|dir
#说明:
-c, --create create a new archive 创建一个归档文件
-v, --verbose verbosely list files processed 显示创建归档文件的进程
-f, --file=ARCHIVE use archive file or device ARCHIVE 后面要立刻接被处理的档案名,比如--file=examples.tar
#举例:
tar -cvf file.tar file1 #file1文件
tar -cvf file.tar file1 file2 #file1,file2文件
tar -cvf file.tar dir #dir目录
tar 解压命令
tar -xvf examples.tar (解压至当前目录下)
tar -xvf examples.tar -C /path (/path 解压至其它路径)
#说明:
-x, --extract, extract files from an archive 从一个归档文件中提取文件
#举例:
tar -xvf file.tar
tar -xvf file.tar -C /temp #解压到temp目录下
tgz压缩命令
(tar.gz,tgz格式是相同的,命名不同而已)
tar -zcvf examples.tgz examples (examples当前执行路径下的目录)
说明:
-z, --gzip filter the archive through gzip 通过gzip压缩的形式对文件进行归档
举例:
tar -zcvf file.tgz dir #dir目录
tgz 解压命令
tar -zxvf examples.tar (解压至当前执行目录下)
tar -zxvf examples.tar -C /path (/path 解压至其它路径)
举例:
tar -zcvf file.tgz
tar -zcvf file.tgz -C /temp
gzip压缩
gzip -d examples.gz examples
gzip解压
gunzip examples.gz
zip
zip 格式是开放且免费的,所以广泛使用在 Windows、Linux、MacOS 平台,要说 zip
有什么缺点的话,就是它的压缩率并不是很高,不如 rar及 tar.gz 等格式。
压缩:
zip -r examples.zip examples (examples为目录)
解压:
zip examples.zip
rar
压缩:
rar -a examples.rar examples
解压:
rar -x examples.rar
替换文本内容
.,$s/192.168.1.101/10.147.18.29/g
192.168.1.101 需要替换的内容
10.147.18.29 替换的内容
此替换命令是从当前光标所在行开始往下替换
命令编辑及光标移动
这里有很多快捷键可以帮我们修正自己的命令。接下来使用光标二字代替光标的位置。
删除从开头到光标处的命令文本
ctrl + u,例如:
$ cd /proc/tty;ls -al光标
如果此时使用ctrl + u快捷键,那么该条命令都会被清除,而不需要长按backspace键。
删除从光标到结尾处的命令文本
ctrl+k,例如:
$ cd /proc/tty光标;ls -al
如果此时使用ctrl + k快捷键,那么从光标开始处到结尾的命令文本将会被删除。
还有其他的操作,不再举例,例如:
ctrl + a: 光标移动到命令开头
ctrl + e:光标移动到命令结尾
alt f:光标向前移动一个单词
alt b:光标向前移动一个单词
ctrl w:删除一个词(以空格隔开的字符串)
历史命令快速执行
我们都知道history记录了执行的历史命令,而使用!+历史命令前的数字,可快速执行历史命令。另外,还可以使用ctrl+r搜索执行过的命令。
部分历史命令查看
history会显示大量的历史命令,而fs -l只会显示部分。
history 10
-c 清除历史
-r 恢复历史
实时查看日志
$ tail -f filename.log
tail -f 加文件名,可以实时显示日志文件内容。当然,使用less命令查看文件内容,并且使用shift+f键,也可达到类似的效果。
磁盘或内存情况查看
怎么知道当前磁盘是否满了呢?
$ df -h/dev/sda14 4.6G 10M 4.4G 1% /tmp/dev/sda11 454M 366M 61M 86% /boot/dev/sda15 55G 18G 35G 35% /home/dev/sda1 256M 31M 226M 12% /boot/efitmpfs 786M 64K 786M 1% /run/user/1000
使用df命令可以快速查看各挂载路径磁盘占用情况。
当前目录各个子目录占用空间大小
如果你已经知道home目录占用空间较大了,你想知道home目录下各个目录占用情况:
$ du -h –-max-depth=1 /home(或者-d 1)18G /home/hyb16K /home/lost+found18G /home/
这里指定了目录深度,否则的话,它会递归统计子目录占用空间大小,可自行尝试。
当前内存使用情况
$ free -h
total used free shared buff/cache availableMem: 7.7G 3.5G 452M 345M 3.7G 3.5GSwap: 7.6G 0B 7.6G
通过free的结果,很容易看到当前总共内存多少,剩余可用内存多少等等。
使用-h参数
不知道你是否注意到,我们在前面几个命令中,都使用了-h参数,它的作用是使得结果以人类可读的方式呈现,所以我们看到它呈现的单位是G,M等,如果不使用-h参数,可以自己尝试一下会是什么样的结果呈现。
根据名称查找进程id
想快速直接查找进程id,可以使用:
$ pgrep hello22692
或者:
$ pidof hello22692
其中,hello是进程名称。
根据名称杀死进程
一般我们可以使用kill -9 pid方式杀死一个进程,但是这样就需要先找到这个进程的进程id,实际上我们也可以直接根据名称杀死进程,例如:
$ killall hello
或者:
$ pkill hello
查看进程运行时间
可以使用下面的命令查看进程已运行时间:
$ ps -p 24525 -o lstart,etime STARTED ELAPSEDSat Mar 23 20:52:08 2019 02:45
其中24525是你要查看进程的进程id。
快速目录切换
cd - 回到上一个目录
cd 回到用户家目录
多条命令执行
我们知道使用分号隔开可以执行多条命令,例如:
$ cd /temp/log/;rm -rf *
但是如果当前目录是/目录,并且/temp/log目录不存在,那么就会发生激动人心的一幕:
bash: cd: /temp/log: No such file or directory(突然陷入沉默)
因为;可以执行多条命令,但是不会因为前一条命令失败,而导致后面的不会执行,因此,cd执行失败后,仍然会继续执行rm -rf *,由于处于/目录下,结果可想而知。
所以你还以为这种事故是对rf -rf *的力量一无所知的情况下产生的吗?
如果解决呢?很简单,使用&&,例如:
$ cd /temp/log/&&rm -rf *
这样就会确保前一条命令执行成功,才会执行后面一条。
查看压缩日志文件
有时候日志文件是压缩的,那么能不能偷懒一下,不解压查看呢?当然可以啦。
例如:
$ zcat test.gztest log
或者:
$ zless test.gztest log
清空文件内容
比如有一个大文件,你想快速删除,或者不想删除,但是想清空内容:
>filename
将日志同时记录文件并打印到控制台
在执行shell脚本,常常会将日志重定向,但是这样的话,控制台就没有打印了,如何使得既能记录日志文件,又能将日志输出到控制台呢?
$ ./test.sh |tee test.log
终止并恢复进程执行
我们使用ctrl+z 暂停一个进程的执行,也可以使用fg恢复执行。例如我们使用
$ cat filename
当我们发现文件内容可能很多时,使用ctrl+z暂停程序,而如果又想要从刚才的地方继续执行,则只需要使用fg命令即可恢复执行。或者使用bg使得进程继续在后台执行。
计算程序运行时间
我们可能会进程写一些小程序,并且想要知道它的运行时间,实际上我们可以很好的利用time命令帮我们计算,例如:
$ time ./fibo 30the 30 result is 832040real 0m0.088suser 0m0.084ssys 0m0.004s
它会显示系统时间,用户时间以及实际使用的总时间。
查看内存占用前10的进程
$ ps -aux|sort -k4nr |head -n 10
这里综合使用了ps,sort,head命令。
快速查找你需要的命令
我们都知道man可以查看命令的帮助手册,但是如果我们想要某个功能却不知道使用哪个命令呢?别着急,还是可以使用man:
$ man -k "copy files"cp (1) - copy files and directoriescpio (1) - copy files to and from archivesgit-checkout-index (1) - Copy files from the index to the working treegvfs-copy (1) - Copy filesgvfs-move (1) - Copy filesinstall (1) - copy files and set attributes
使用-k参数,使得与copy files相关的帮助手册都显示出来了。
命令行下的复制粘贴
我们知道,在命令行下,复制不能再是ctrl + c了,因为它表示终止当前进程,而控制台下的复制粘贴需要使用下面的快捷键:
ctrl + insert
shift + insert
搜索包含某个字符串的文件
例如,要在当前目录下查找包含test字符串的文件:
$ grep -rn "test"test2.txt:1:test
它便可以找到该字符串在哪个文件的第几行。
屏幕冻结
程序运行时,终端可能输出大量的日志,你想简单查看一下,又不想记录日志文件,此时可以使用ctrl+s键,冻结屏幕,使得日志不再继续输出,而如果想要恢复,可使用ctrl+q退出冻结。
无编辑器情况下编辑文本文件
如果在某些系统上连基本的vi编辑器都没有,那么可以使用下面的方式进行编辑内容:
$ cat >file.txtsome words(ctrl+d)
编辑完成后,ctrl+d即可保存。
查看elf文件
查看elf文件头信息
例如:
$ readelf -h filename
我们在显示结果中,可以看到运行的平台,elf文件类型,大小端情况等。
查看库中是否包含某个接口
$ nm filename |grep interface
这里是从文件filename中查看是否包含interface接口,前提是该文件包含符号表。
查看日志
线上出现了问题,登上线上的机器查日志是非常常见的操作了。我第一次登上线上机器查日志的时候,我还只记得以下的几个命令(假设现在我们的日志文件叫做service.log):
cat service.log
tail -f service.log
vim serivice.log
(明显是不够用的)
现在日志每天产出的大小大概1GB:
每天产出1GB大小的日志
每天产出1GB大小的日志
如果是小文件的话,单纯的cat命令还是可以应付的,但如果你直接用cat命令打开一个1GB的日志文件,保证卡死你(ctrl + c退出cat命令需要很久才能将cat命令停下来)。
一般我只用cat来查看这个小文件的文本内容是什么
同样地,如果是小文件,单纯的vim命令去打开文件也是可以应付的,但如果你用vi命令去打开一个1GB甚至更大的文件,也能明显感受到缓慢和卡顿。
平时我还是很喜欢用vi去查找对应的记录的,我一般的操作:
vi service
在命令模式下
按G跳转到文件的末尾
输入 / 关键字搜索对应的记录
按n往上查询,按N往下查询
tail -f service.log
这个命令我一般用于查看流量是否进来了(或者调试的时候可以直接看到日志,再迅速ctrl +c关掉)
面对比较大的日志文件,这我们就得配合grep来玩了,比如我们现在得知某个手机号收不到短信验证码,想要看一下这个手机号的日志是怎么样的。于是我们就可以这样搞:
cat service.log | grep 13888888888
这么一搞,就能将service.log中所有含有13888888888的记录给搜出来,搜索的速度还是贼快的。
检索日志
检索日志
现在我们已经能根据关键字搜到对应的记录了,接着我想看一下那条记录的日志上下文【这样就能知道这条数据大概的执行状态了】
首先,我们先要查出对应记录的行号,在cat 命令后面加上一个 -n 参数就好了。所以命令是:cat -n service.log | grep 13888888888 ,如下图我们就可以查到对应的行号了
查看行数
现在行数是29506,我们一般只要看一下29506的前10行和后10行就差不多知道问题出现在哪了,于是我们可以这样做:
sed -n “29496,29516p” service.log:从29496行开始检索,到29516行结束
cat -n service.log | tail -n +29496 | head -n 20:从29496行开始检索,往前推20条
如果关键字不太准确(日志输出的记录太多了),我们可以使用more命令来浏览或者输出到文件上再分析:
cat service.log | grep 13 |more :将查询后的结果交由more输出
cat service.log | grep 13 > /home/sanwai/aa.txt 将查询后的结果写到/home/sanwai/aa.txt文件上
有的时候,我们想统计这个日志输出了多少行,我们可以使用这条命令:
cat service.log | wc -l
查看行数
查看行数
参考资料:
https://www.cnblogs.com/xiashan17/p/7059978.html
查进程和端口
查进程有两个命令:
ps -ef
ps aux
上面两个命令都是列出所有的进程,我们还是通过 |管道和grep 来过滤掉想要查的进程,比如说:ps -ef |grep java
把进程查出来干嘛?知道它的进程ID了,我们可以把他给杀掉。
kill -9 processId:杀掉某个进程
查端口也是一个很常见的操作,常见命令:netstat -lntup:
l:listening n:num t:tcp u:udp p:display PID/Program name for sockets
查看当前所有tcp/udp端口的信息
查看某个端口详细的信息:lsof -i:4000
查看某个端口的详细信息
查看某个端口的详细信息
三、查看系统的状态
3.1 TOP实时查看进程的状态
TOP命令查看进程的状态,其中有个load average可能不是那么好理解,下面来解释一下:
load average:在特定时间间隔内运行队列中(在CPU上运行或者等待运行多少进程)的平均进程数。
load average 有三个值,分别代表:1分钟、5分钟、15分钟内运行进程队列中的平均进程数量。
正在运行的进程 + 准备好等待运行的进程 在特定时间内(1分钟,5分钟,10分钟)的平均进程数
Linux进程可以分为三个状态:
阻塞进程
可运行的进程
正在运行的进程
比如现在系统有2个正在运行的进程,3个可运行进程,那么系统的load就是5,load average就是一定时间内的load数量均值。
3.2free查看内存使用状况
linux的内存管理机制的思想包括(不敢说就是)内存利用率最大化,内核会把剩余的内存申请为cached,而cached不属于free范畴。
如果free的内存不够,内核会把部分cached的内存回收,回收的内存再分配给应用程序。所以对于linux系统,可用于分配的内存不只是free的内存,还包括cached的内存(其实还包括buffers)。
可用内存=free的内存+cached的内存+buffers
Buffer Cache和Page Cache。前者针对磁盘块的读写,后者针对文件inode的读写。这些Cache有效缩短了 I/O系统调用(比如read,write,getdents)的时间。磁盘的操作有逻辑级(文件系统)和物理级(磁盘块)
//可以防止日志爆盘,将所有标准输出及标准错误输出到/dev/null空设备,即没有任何输出信息。
nohup ./filebeat -e -c filebeat.yml >/dev/null 2>&1 &
常用命令
1、du -a -h ./ 查看当前目录下所有文件的大小 ,du -a -h –-max-depth=1 ./ 超过指定层数的目录后,予以忽略
2、trace com.nrec.pcs9000.app.service.impl.AstSgassetServiceImpl getAssetTreeMaps --skipJDKMethod false 查看包含jdk调用
3、trace com.nrec.pcs9000.app.service.impl.AstSgassetServiceImpl *getAssetTreeMaps* 查看方法内部的所有调用耗时包含lambda、jdk调用
4、watch com.nrec.pcs9000.app.service.impl.AstSgassetServiceImpl getAssetTreeMaps params -x 2查看方法参数详细内容
shell脚本学习
windows *.bat
linux: *.sh
shebang
开头的第一行以 :#! /bin/bash
接收参数的方式为 $0 $1…. 注意,$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。
#!/bin/bash
funWithParam(){
echo "第一个参数为 $1 !"
echo "第二个参数为 $2 !"
echo "第十个参数为 $10 !"
echo "第十个参数为 ${10} !"
echo "第十一个参数为 ${11} !"
echo "参数总数有 $# 个!"
echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
调用shell脚本是传参和调用函数传参一样 sh test.sh 1 2 3 4 5 ….
参数处理 | 说明 |
---|---|
$# | 传递到脚本或函数的参数个数 |
$* | 以一个单字符串显示所有向脚本传递的参数 |
$$ | 脚本运行的当前进程ID号 |
$! | 后台运行的最后一个进程的ID号 |
$@ | 与$*相同,但是使用时加引号,并在引号中返回每个参数。 |
$- | 显示Shell使用的当前选项,与set命令功能相同。 |
$? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
函数必须要先定义,不能结尾出现,函数调用直接函数名称 ,获取值用 $?
#! /bin/bash
funWithReturn(){
echo "这个函数会对输入的两个数字进行相加运算..."
echo "输入第一个数字: "
read aNum
echo "输入第二个数字: "
read anotherNum
echo "两个数字分别为 $aNum 和 $anotherNum !"
return $(($aNum+$anotherNum))
}
funWithReturn
echo "输入的两个数字之和为 $? !"
read 函数等待用户输入
参数赋值:但是只能赋值一次,第二次获取为空,赋值的=前后不能为空
stest(){
return 77
}
echo "调用test函数"
stest
stestV=$?
stestV2=$?
echo "stestV:===== ${stestV}"
echo "stestV2:===== ${stestV2}"
调用test函数
stestV:===== 77
stestV2:===== 0
获取pid信息
pid=`ps -ef|grep 'mysql'|grep -v grep|awk '{print $2}'`
echo "3306.PID= $pid"
脚本权限
// 添加执行权限
chmod +x shell.sh
案例
下载图片然后base64编码返回
#!/bin/bash
# 下载图片
curl -s $2 -o $1
# 对图片进行编码
img="data:image/"$fmt";base64, $(base64 -w 0 "$1")"
# 删除图片
rm -f $1
输出base64编码信息
echo "$img"
#!/bin/bash
# yhc 2023年3月3日 不要删除 ai官网项目会调用这个脚本!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
agent=('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36' 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/109.0' 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.50' 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 OPR/26.0.1656.60')
length=${#agent[@]}
rand=$(($RANDOM%$length+1))
valuen=${agent[$rand-1]}
# 下载图片
curl -s -o $1 -X GET $2 -H "User-Agent: $valuen" -H "Referer: https://google.com/"
# 对图片进行编码
img="$(base64 -w 0 "$1")"
# 删除图片
rm -f $1
echo "$img"
#!/bin/bash
#########################################################
# Version :1.0 #
# Date :2022-12-29 #
# Author :yhc #
#########################################################
path=/opt/docker/nrcloud/nrcloud-base/
dir=('eureka' 'per' 'auth' 'audit' 'agent' 'gateway')
method(){
for var in ${dir[@]}
do
echo "进入${path}${var}"
cd ${path}${var}
$1
echo '=================================='
done
}
start(){
echo '启动nrcloud 微服务开始'
method 'docker-compose up -d'
echo '启动nrcloud 微服务完成'
}
stop(){
echo '停止nrcloud 微服务开始'
method 'docker-compose down'
echo '停止nrcloud 微服务完成'
}
restart(){
stop
start
}
case $1 in
'start')
start
;;
'stop')
stop
;;
'restart')
restart
;;
*) echo '输入错误'
;;
esac