Ubuntu常用命令(不断补充中)
个人常用命令集锦,比方查看硬件信息或者文件操作,查找定位等等,由于积累的多了,太长了,所以这里列出目录方便查找。[toc]
性能&监控
监控CPU使用情况:watch grep "cpu MHz" /proc/cpuinfo
监控GPU使用情况:watch -n .1 nvidia-smi
查看GPU使用情况(安装查看:https://github.com/wookayin/gpustat):gpustat
清理未被访问的内存数据:sudo sh -c "sync; echo 3 > /proc/sys/vm/drop_caches"
查看内存(适用于Xen虚拟机。查看实体内存):sudo dmidecode -t memory | grep Size
查看内存:free -m(以MB为单位)或者free -g(以GB为单位)
杀死用户username的所有进程:pkill -u username
硬件信息
CPU
总核数 = 物理CPU个数 X 每颗物理CPU的核数
总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数
# 查看物理CPU个数:cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l
查看每个物理CPU中core的个数(即核数):cat /proc/cpuinfo| grep "cpu cores"| uniq
查看逻辑CPU的个数:cat /proc/cpuinfo| grep "processor"| wc -l
查看CPU信息(型号):cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c
参考:Linux查看物理CPU个数、核数、逻辑CPU个数 - emanlee - 博客园http://www.cnblogs.com/emanlee/p/3587571.html
系统信息
内存
查看内存信息:cat /proc/meminfo
查看内存大小:free -m,单位是MB,也可以用top或htop
使用和更多命令参数使用参考:ubuntu 查看内存命令 - jzp12的专栏 - 博客频道 - CSDN.NEThttp://blog.csdn.net/jzp12/article/details/7560450
用户权限
添加新用户名为zhang:sudo adduser zhang
注意:不要使用useradd,登陆时候shell有问题(默认登录是sh)
删除用户zhang:sudo userdel zhang
给zhang用户添加密码:sudo passwd zhang
修改文件夹的所属用户和组:sudo chown -R yuens.yuens abc
给用户abc添加到sudo组:
#查看当前用户所属组
groups
#查看指定用户abc所属组
groups abc
#添加用户abc到docker组
sudo usermod -a -G sudo abc
参考:Docker Got permission denied http://www.myexception.cn/operating-system/2173364.html
删除sudo分组中的abc用户:sudo vim /etc/group,找到对应sudo分组,删掉用户名abc
程序代码安装
一、基本概念
1.1、什么是库
在 windows 平台和 linux 平台下都大量存在着库。本质上来说库是一种可执行的二进制代码(但不可以独立执行),可以被操作系统载入内存执行。由于 windows 和 linux 的平台不同(主要是编译器、汇编器和连接器 的不同),因此二者库的二进制是不兼容的。这里仅介绍 linux下的库。
1.2、 库的种类
linux 下的库有两种:静态库和共享库(动态库)。二者的不同点在于代码被载入的时刻不同:
静态库的代码在编译过程中已经被载入可执行程序,因此生成的可执行程序体积较大。静态用.a为后缀, 例如: libhello.a
共享库(动态库)的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此生成的可执行程序代码体积较小。
动态通常用.so为后缀, 例如:libhello.so。共享库(动态库)的好处是:不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。为了在同一系统中使用不同版本的库,可以在库文件名后加上版本号为后缀,例如: libhello.so.1.0,由于程序连接默认以.so为文件后缀名。所以为了使用这些库,通常使用建立符号连接的方式。
ln -s libhello.so.1.0 libhello.so.1
ln -s libhello.so.1 libhello.so
1.3 静、动态库在linux下的生成
以下面的代码为例,生成上面用到的hello库:
/* hello.c */
#include "hello.h"
void sayhello()
{
printf("hello,world ");
}
首先用gcc编绎该文件,在编绎时可以使用任何合法的编绎参数,例如-g加入调试代码等:
gcc -c hello.c -o hello.o
1、生成静态库 生成静态库使用ar工具,其实ar是archive的意思:
ar cqs libhello.a hello.o
2、生成动态库 用gcc来完成,由于可能存在多个版本,因此通常指定版本号:
gcc -shared -o libhello.so.1.0 hello.o
1.4、库文件的命名规范
在 linux 下,库文件一般放在/usr/lib和/lib下:
静态库的名字一般为libxxxx.a,其中 xxxx 是该lib的名称;
动态库的名字一般为libxxxx.so.major.minor,xxxx 是该lib的名称,major是主版本号,minor是副版本号
1.5、可执行程序在执行的时候如何定位共享库(动态库)文件 :
当系统加载可执行代码(即库文件)的时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径,此时就需要系统动态载入器 (dynamic linker/loader)
对于 elf 格式的可执行程序,是由 ld-linux.so* 来完成的,它先后搜索 elf 文件的 DT_RPATH 段–>环境变量LD_LIBRARY_PATH—->/etc/ld.so.cache 文件列表–> /lib/,/usr/lib 目录找到库文件后将其载入内存。如: export LD_LIBRARY_PATH=’pwd’ ,即将当前文件目录添加为共享目录。
1.6、使用ldd工具 ,查看可执行程序依赖那些动态库或着动态库依赖于那些动态库:
ldd 命令可以查看一个可执行程序依赖的共享库, 例如
ldd /bin/lnlibc.so.6
=> /lib/libc.so.6 (0×40021000)/lib/ld-linux.so.2
=> /lib/ld- linux.so.2 (0×40000000)
可以看到 ln 命令依赖于 libc 库和 ld-linux 库
1.7、使用nm工具 ,查看静态库和动态库中有那些函数名;
(T类表示函数是当前库中定义的,U类表示函数是被调用的,在其它库中定义的,W类是当前库中定义,被其它库中的函数覆盖):
有时候可能需要查看一个库中到底有哪些函数,nm工具可以打印出库中的涉及到的所有符号,这里的库既可以是静态的也可以是动态的。nm列出的符号有很多, 常见的有三种::
T类:是在库中定义的函数,用T表示,这是最常见的;
U类:是在库中被调用,但并没有在库中定义(表明需要其他库支持),用U表示;
W类:是所谓的“弱态”符号,它们虽然在库中被定义,但是可能被其他库中的同名符号覆盖,用W表示。
例如,假设开发者希望知道上文提到的hello库中是否引用了 printf():
nm libhello.so | grep printf
#或者
nm -D libhello.so
发现printf是U类符号,说明printf被引用,但是并没有在库中定义。由此可以推断,要正常使用hello库,必须有其它库支持,使用ldd工具查看hello依赖于哪些库:
ldd libhello.so
libc.so.6=>/lib/libc.so.6(0x400la000)
/lib/ld-linux.so.2=>/lib/ld-linux.so.2 (0x40000000)
文件基本操作
文件大小
查看当前路径下XXX文件的大小:du -sh XXX
统计`log_file`文件中每行出现的次数:`sort log_file | uniq -c`。
文件执行权限
要让文件有能够执行的权限:chmod +x ./abc.sh
文件计数
按照时间列出文件:ls -Stl
按照友好方式列出文件大小:ls -hl
统计当前文件夹下文件的个数 :ls -l |grep "^-"|wc -l
统计当前文件夹下目录的个数 :ls -l |grep "^-"|wc -l
统计当前文件夹下文件的个数 ,包括子文件夹里的:ls -lR|grep "^-"|wc -l
统计文件夹下目录的个数 ,包括子文件夹里的:ls -lR|grep "^d"|wc -l
md5对比
MD5算法常常被用来验证网络文件传输的完整性,防止文件被人篡改。MD5 全称是报文摘要算法(Message-Digest Algorithm 5),此算法对任意长度的信息逐位进行计算,产生一个二进制长度为128位(十六进制长度就是32位)的“指纹”(或称“报文摘要”),不同的文件产生相同的报文摘要的可能性是非常非常之小的。
在linux或Unix上,md5sum是用来计算和校验文件报文摘要的工具程序。一般来说,安装了Linux后,就会有md5sum这个工具,直接在命令行终端直接运行。
生成文件a的md5:md5sum ./a.txt
生成a文件的md5并保存为文件:md5sum ./a.txt >> ./a.txt.md5
md5sum [OPTION]... [FILE]...-b 或 --binary :把输入文件作为二进制文件看待。
-t 或 --text :把输入的文件作为文本文件看待(默认)。
-c 或 --check :用来从文件中读取md5信息检查文件的一致性。(不细说了参见info)
--status :这个选项和check一起使用,在check的时候,不输出,而是根据返回值表示检查结果。
-w 或 --warn :在check的时候,检查输入的md5信息又没有非法的行,如果有则输出相应信息。
ps:感觉这个-c参数用的时候有点问题
参考:linux比较两个文件是否一样(linux命令md5sum使用方法)_LINUX_操作系统_脚本之家http://www.jb51.net/LINUXjishu/123859.html
Linux下md5sum 校验文件完整性_Linux教程_Linux公社-Linux系统门户网站
http://www.linuxidc.com/Linux/2014-03/98416.htm
挂载硬盘
拷贝数据到移动硬盘,先查看当前的设备有哪些没有mount:sudo fdisk -l
注意NTFS的硬盘格式也可以挂载但需要安装其他的软件(我查了下比较麻烦),还好我的盘是exFAT格式。
然后创建一个文件夹data1在根目录,并把这个设备mount到这个文件夹:
sudo mkdir /data1
sudo mount /dev/sdc1 /data1
此时,进入根目录/data1就能看到这个硬盘设备里的东西了。如果是多个分区可能会有多个/dev/sdc1,/dev/sdc2之类的,可以逐个挂载。
拷贝完成数据或者操作后,需要umount硬盘 :sudo umount /data1
没有提示表示成功卸载设备,可以用sudo fdisk -l命令再次检查一下是否卸载成功,完成后即可拔下硬盘设备。
参考:Linux mount命令 | 菜鸟教程http://www.runoob.com/linux/linux-comm-mount.html
Linux上挂载NTFS分区 - jiu~ - 博客园
http://www.cnblogs.com/jiu0821/p/6489249.html
建立软连接
ln的链接分为软链接和硬链接两种。
1. 软链接就是ln –s ** **,它只会在你选定的位置上生成一个文件的镜像,不会占用磁盘空间
2. 硬链接ln ** **,没有参数-s, 它会在你选定的位置上生成一个和源文件大小相同的文件
无论是软链接还是硬链接,文件都保持同步变化。
如果你用ls察看一个目录时,发现有的文件后面有一个@的符号,那就是一个用ln命令生成的文件,用ls –l命令去察看,就可以看到显示的link的路径了。
Linux/Unix 档案系统中,有所谓的连结(link),我们可以将其视为档案的别名,而连结又可分为两种 : 硬连结(hard link)与软连结(symbolic link),硬连结的意思是一个档案可以有多个名称,而软连结的方式则是产生一个特殊的档案,该档案的内容是指向另一个档案的位置。硬连结是存在同一个档案系统中,而软连结却可以跨越不同的档案系统。
范例:
例1:将档案 yy 产生一个 symbolic link : zz
ln -s yy zz
文件夹建立软链接(用绝对地址)
ln -s 源文件地址(当前文件地址) 目的地址(待建立链接的地址)
比如我把Linux文件系统rootfs_dir软链接到/home/jyg/目录下
ln -s /opt/linux/rootfs_dir /home/jyg/rootfs_dir 就可以了
例2:将档案 yy 产生一个 hard link : zz
ln yy xx
更多参数使用见参考。
ubuntu文件夹建立软链接方法 - - 博客频道 - CSDN.NET
http://blog.csdn.net/jiuyueguang/article/details/9350859
文件拷贝rsync(这个命令有点诡异==,能用scp就用scp,进度通过du -sh来查看)
文件拷贝cp
第一种:实现同名文件重命名的拷贝
给出shell脚本(但实际这段脚本还是有点问题,实现的是第三种):
#!/bin/bash
from_path="/home/enyu/222/"
to_path="/home/enyu/111/"
file=`ls ${from_path}`
for filename in $file
do
if [ -e "${target_path}${filename}" ];then
cp ${from_path}${filename} ${to_path}${filename}_old
else
cp ${from_path}${filename} ${to_path}${filename}
fi
done
Qt5安装
sudo apt install -y qt-default qtcreator qtdeclarative5-dev
软件压缩与解压
7z格式
压缩为7z格式
首先安装:sudo apt-get install p7zip p7zip-full p7zip-rar
将yajiu.jpg和yajiu.png压缩成一个7z包:7z a yajiu.7z yajiu.jpg yajiu.png
将所有.jpg的文件压缩成一个7z包:# 7z a yajiu.7z *.jpg
将文件夹yajiu压缩成一个7z包:7z a yajiu.7z yajiu
参考:Linux 下压缩与解压.zip和.rar及.7z文件-kowems-ChinaUnix博客http://blog.chinaunix.net/uid-27666459-id-3993688.html
解压7z
解压到当前目录下:7z x ./xxx.7z
解压到指定目录下:7z x ./xxx.7z ~/Software
参考:Ubuntu Linux 安装 .7z 解压和压缩文件 - zqlovlg的专栏 - 博客频道 - CSDN.NEThttp://blog.csdn.net/zqlovlg/article/details/8033456
tar.gz
解压tar.gz
比方下载aliedit.tar.gz,首先解压:tar -zxvf aliedit.tar.gz,或者 tar -xvf aliedit.tar.gz
之后安装:./aliedit.sh
.bz2
据说这种压缩率很高:
解压abc.tar.bz2:tar -xjf abc.tar.bz2
压缩当前路径下所有jpg文件为bz2格式的压缩包abc.tar.bz2:tar -cjf abc.tar.bz2 *.jpg
.tar后缀
解压:tar -xvf xxxxx.tar
rar
需先安装:sudo apt-get install unrar
压缩/etc目录为etc.rar:rar a etc.rar /etc
解压etc.rar:
rar x etc.rar
unrar -e etc.tar
gz解压
方法一:gzip -b java.gz
方法二:使用zcat 命令,然后将标准输出 保存文件 zcat java.gz > java.java
参考:https://www.cnblogs.com/wangshouchang/p/7748527.html
查找与定位
查找某命令安装位置如ls命令:which ls
统计某文档行数:wc -l /etc/httpd/conf/httpd.conf
查找当前路径下的所有文件内容中 包含XXX名字的文件:grep -rn "XXX"或grep -rn XXX(不需要前后加上*)
查找当前路径下的所有文件名 包含XXX的文件:find . -name "*XXX*"
查询软件安装位置(这里以sphinxsearch为例):whereis sphinxsearch
在vim中查找关键词xxx,进入vim后输入?然后输入xxx回车,输入小写n(跳到上一个关键词的位置),输入大写N,跳到下一个关键词的位置
more命令,功能类似 cat ,cat命令是整个文件的内容从上到下显示在屏幕上。 more会以一页一页的显示方便使用者逐页阅读,而最基本的指令就是按空白键(space)就往下一页显示,按 b 键就会往回(back)一页显示,而且还有搜寻字串的功能 。more命令从前向后读取文件,因此在启动时就加载整个文件。(该命令还有更多用法,见参考)
参考:linux more命令的使用 - Linux操作系统:Ubuntu_Centos_Debian - 红黑联盟
http://www.2cto.com/os/201310/250257.html
任务管理进程
查询进程是否开启(这里以search为例):ps -aux | grep searchd
强行停止正在运行的进程:先查看需要停下进程的pid(如22222),然后用命令kill 22222
查看当前运行的所有进程:top或htop
查看当前用户正在进行的任务:ps -a
通过sub-shell让进程在后台运行HUP(hangup),例如:(python ./test.py &)
更多详细Linux 技巧:让进程在后台可靠运行的几种方法
http://www.ibm.com/developerworks/cn/linux/l-cn-nohup/
hangup 名称的来由 :在 Unix 的早期版本中,每个终端都会通过 modem 和系统通讯。当用户 logout 时,modem 就会挂断(hang up)电话。 同理,当 modem 断开连接时,就会给终端发送 hangup 信号来通知其关闭所有子进程。
将脚本在后台执行,并将控制台的输出结果在新建的log文件中保存:(./test.sh > ./test.log &),如果是追加方式,则将>改为>>,即:(./test.sh >> ./test.log &)
挂起正在执行的任务:ctrl+z,此时进程会在后台挂起并停下。再用fg可以将后台挂起的进行重新放回前台,也可以用bg将挂起的进程放在后台运行(但其实这样会占用当前的终端),fg则是将挂起的进程放在前台执行。
杀死命令中带有LOCAL=NO的命令:ps -ef|grep LOCAL=NO |grep -v grep|cut -c 9-15|xargs kill -9
参考:Linux下批量Kill多个进程的方法_LINUX_操作系统_脚本之家
http://www.jb51.net/LINUXjishu/43534.html
灵活运用 CTRL-z
在我们的日常工作中,我们可以用 CTRL-z 来将当前进程挂起到后台暂停运行,执行一些别的操作,然后再用 fg 来将挂起的进程重新放回前台(也可用 bg 来将挂起的进程放在后台,也可用fg将挂起的进程放到前台,比方之前挂起的是vim)继续运行。这样我们就可以在一个终端内灵活切换运行多个任务,这一点在调试代码时尤为有用。因为将代码编辑器挂起到后台再重新放回时,光标定位仍然停留在上次挂起时的位置,避免了重新定位的麻烦。
软件安装下载卸载
apt-get install因缺少依赖包安装失败:sudo apt-get -f install
删除(yuenshome)文件夹(首先获取权限):sudo chmod 777 yuenshome; rm -rf yuenshome
Linux端点续传后台下载命令wget -c http://123.com/abc.deb
彻底卸载某软件softname1(见后文)
从根目录查找包含cuda的文件夹或文件:find / | grep cuda
查看本机ip地址(apt install -y net-tools):ifconfig -a
Linux端点续传后台下载命令wget
命令wget -c -b http://abc.com/file.zip,断点续传下载(-c参数表示继续下载,-b代表后台下载,产生下载日志wget-log文件)。
参考
wget 使用的15个震撼例子 - Ant - 博客频道 - CSDN.NET http://blog.csdn.net/mathgeophysics/article/details/9399119
彻底卸载某软件softname1
找到此软件名称,然后sudo apt-get purge softname1,purge参数为彻底删除文件,然后sudo apt-get autoremove,sudo apt-get clean和dpkg -l |grep ^rc|awk ‘{print $2}’ | sudo xargs dpkg -P 两条命令来清除残余的配置文件。再来一次sudo apt-get remove –purge softname1,然后用sudo apt-get update来更新一新软件信息。
参考
ubuntu彻底卸载软件_百度知道
http://zhidao.baidu.com/link?url=An0KLuefJv8-DUbQ7VbLF1i_i5SjT3NFd0IF2DjK4-Ou-w2I8XRXoKpHHYjfE-hZyapQBtG2baY8sa5cbK4ywq
Terminal下查看Ubuntu操作系统位数及版本_Linux教程_Linux公社-Linux系统门户网站
http://www.linuxidc.com/Linux/2014-05/101121.htm
服务器运维
要封停一个IP,使用下面这条命令:
iptables -I INPUT -s ***.***.***.*** -j DROP
要解封一个IP,使用下面这条命令:
iptables -D INPUT -s ***.***.***.*** -j DROP
参考:安全组规则的设置|云服务器 ECS - 开发者论坛
https://bbs.aliyun.com/read/285602.html
关机命令,30小时后自动关机:sudo shutdown -t $[30*60]
取消关机命令:sudo shutdown -c
立刻关机/重启:sudo shutdown now,sudo reboot now
远程连接服务器,带端口:ssh -p 4499 yuens@127.0.0.1
不带端口:ssh yuens@127.0.0.1
将远端的localhost:8888端口映射到本地8008端口:ssh -L8008:localhost:8888 yuens@121.121.121.121
跨过跳板机连接服务器:ssh yuens@目标服务器IP -p 22 -o ProxyCommand='ssh -p 22 yuens@跳板机IP -W %h:%p'
目前的问题是密码需要输入两次,==
参考:ssh如何通过跳板机直接访问到后端服务器(Mac&Linux&Windows解决方案) - 永福的博客https://my.oschina.net/foreverich/blog/657075
注:scp不支持断点续传
发送文件到服务器:scp ./caffe.zip yuens@111.111.111.111:~/download/
指定端口发送(-P,p大写):scp -P 4500 ./caffe.zip yuens@111.111.111.111:~/download/
从服务器下载文件到本地:scp yuens@111.111.111.111:~/download/caffe.zip ./
跨服务器拷贝文件abc.zip:
先执行:scp -P 4510 abc.zip yuens@1.1.1.1:~/
然后键盘输入:ctrl + z,挂载任务;
然后执行:bg,后台继续执行,或者bg > log,将日志输出到log文件里。退出shell也不会停掉scp。
有两个命令用来上传、下载文件(适合中小文件的上传和下载)
rz:在命令行里输入rz,则会出现弹窗选择本地的文件,可以上传到服务器
sz:在命令行里输入sz ./bbb/abc.log,则会将bbb/abc.log文件下载到本地
如果输入rz和sz提示没有这两个命令,就是没安装:sudo apt install lrzsz
网络问题
有一个可能是dns配置不正确:sudo vim /etc/resolv.conf,修改dns配置文件
和windows一样,linux也有hosts文件,可以在这里编辑:sudo vim /etc/hosts
ping前需要安装:sudo apt-get install inetutils-ping
环境变量
Linux的变量种类 按变量的生存周期来划分,Linux变量可分为两类:
永久的:需要修改配置文件,变量永久生效。
临时的:使用export命令声明即可,变量在关闭shell时失效。
设置变量有三种方法:
2.1 在/etc/profile文件中添加变量【对所有用户生效(永久的) 】
用VI在文件/etc/profile文件中增加变量 ,该变量将会对Linux下所有用户有效 ,并且是“永久 的”。
例如:编辑/etc/profile文件,添加CLASSPATH变量
# vi /etc/profile
export CLASSPATH=./JAVA_HOME/lib;$JAVA_HOME/jre/lib
注:修改文件后要想马上生效 还要运行# source /etc/profile 不然只能在下次重进此用户时生效。
2.2 在用户目录下的.bash_profile文件中增加变量【对单一用户生效(永久的) 】
用VI在用户目录下的.bash_profile文件中增加变量,改变量仅会对当前用户有效,并且是“永久的”。例如:编辑guok用户目录(/home/guok)下的.bash_profile(现在叫做~/.bashrc)
$ vi /home/guok/.bash.profile
添加如下内容:
export CLASSPATH=./JAVA_HOME/lib;$JAVA_HOME/jre/lib
注:修改文件后要想马上生效还要运行$ source /home/guok/.bash_profile不然只能在下次重进此用户时生效。
2.3 直接运行export命令定义变量【只对当前shell(BASH)有效(临时的) 】
在shell的命令行下直接使用[export 变量名=变量值] 定义变量,该变量只在当前的shell(BASH)或其子shell(BASH)下是有效的,shell关闭了,变量也就失效了,再打开新shell时就没有这个变量,需要使用的话还需要重新定义。
3.环境变量的查看
3.1 使用echo命令查看单个环境变量。(使用LD_LIBRARY_PATH=""
可以清空该变量值) 例如:
3.2 使用env查看所有环境变量。 例如:
3.3 使用set查看所有本地定义的环境变量。
4.常用的环境变量
PATH 决定了shell将到哪些目录中寻找命令或程序
HOME 当前用户主目录
HISTSIZE 历史记录数
LOGNAME 当前用户的登录名
HOSTNAME 指主机的名称
SHELL 当前用户Shell类型
LANGUGE 语言相关的环境变量,多语言可以修改此环境变量
MAIL 当前用户的邮件存放目录
PS1 基本提示符,对于root用户是#,对于普通用户是$
别名的设置与变量设置方法相同,在不同文件中设置可以使其永久生效或者临时生效, 如:可以在/etc/profile文件中添加 alias ls=’ls –color=auto’ alise ll=’ls -alF’ 设置命令ll 和ls
shell算术运算
加减乘除:
$[100+1]
$[-20-10]
$[10*10]
$[120/10]
直接执行上面会给出一个数字外加command not found,那个数字就是运算的结果,如果不想看到这个数字可以在前面加上echo命令,如echo $[10+10],就不会有命令找不到的报错了。
bc为任意精度算数语言提供解释器,即binary calculator,往往用于实现高精度的计算。
echo "3.14*999." | bc
# 把1000转为2进制
echo 'obase=2;1000' | bc
# 把1000转为8进制
eccho 'obase=8;1000' | bc
当然直接在命令行输入bc进入交互模式也可以用。