跳转至

linux基础操作

熟悉使用基本的Linux命令对于训练模型非常有必要。以下为常用命令使用介绍:

切换当前目录

命令: cd

cd /home    # 进入 '/home' 目录
cd ..   # 返回上一级目录
cd ../.. # 返回上两级目录
cd /    # 返回根目录
cd -    # 返回上次所在的目录

创建目录

命令: mkdir

mkdir test     # 创建test目录
mkdir dir1 dir2     # 同时创建两个目录
mkdir -p /tmp/dir1/dir2     # 递归创建目录树

查看当前路径

命令:pwd

(base) root@host:~/demo/next_dir# pwd
/root/demo/next_dir

查看目录/文件信息

命令:ls

ls  #查看目录中的文件
ls -l   #显示文件和目录的详细资料
ls -a   #列出全部文件,包含隐藏文件
ls -lh  #查看⽂件和⽬录的详情列表(增强⽂件⼤⼩易读性)
ls -lSr     #查看⽂件和⽬录列表(以⽂件⼤⼩升序查看)
ls -R   #连同子目录的内容一起列出(递归列出),等于该目录下的所有文件都会显示出来

复制文件

命令:cp

参数说明:
-a:将文件的特性一起复制
-p:连同文件的属性一起复制,而非使用默认方式,与-a相似,常用于备份
-i:若目标文件已经存在时,在覆盖时会先询问操作的进行
-r:递归持续复制,用于目录的复制行为
-u:目标文件与源文件有差异时才会复制

cp dir/* .     # 复制某目录下的所有文件至当前目录
cp -a dir1 dir2     # 复制目录
cp -a /temp/dir1 .  # 复制一个目录至当前目录

重命名、移动文件/目录

命令:mv

参数说明:
-f:force强制的意思,如果目标文件已经存在,不会询问而直接覆盖
-i:若目标文件已经存在,就会询问是否覆盖
-u:若目标文件已经存在,且比目标文件新,才会更新

mv old_dir new_dir  #重命名⽬录
mv dir_2 dir_1/     # 将dir_2目录移动到dir_1目录下

删除目录/文件

命令:rm

参数说明:
-f:就是force的意思,忽略不存在的文件,不会出现警告消息
-i:互动模式,在删除前会询问用户是否操作
-r:递归删除,最常用于目录删除,它是一个非常危险的参数

rm -f file1     # 删除’file1’⽂件
rmdir dir1   # 删除’dir1’⽬录
rm -rf dir1     # 删除’dir1’⽬录和其内容
rm -rf dir1 dir2    # 同时删除两个⽬录及其内容

查看文件内容

命令:cat

参数说明:
-n:显示行号,会在输出的每一行前加上行号
-b:显示行号,但只对非空行进行编号
-s:压缩连续的空行,只显示一个空行
-E:在每一行的末尾显示 $ 符号
-T:将 Tab 字符显示为 ^I
-v:显示一些非打印字符

cat file1   # 从第一个字节开始正向查看文件的内容
cat -n file1    # 查看文件并展示行数
tac file1   # 从最后一行开始反向查看一个文件的内容
cat file1 file2 > file3     # 将 file1 和 file2 的内容合并到 file3 中
cat -n textfile1 > textfile2    # 把 textfile1 的文档内容加上行号后输入 textfile2 这个文档里

查看文件的开头内容

命令:head

参数说明:
-q: 隐藏文件名
-v: 显示文件名
-c<数目>: 显示的字节数。
-n<行数>: 显示的行数默认为 10,即显示 10 行的内容

head test.log    # 显示 test.log 文件的开头 10 行
head -n 5 test.log      # 显示 test.log 文件的开头 5 行
head -c 20 test.log     # 显示 test.log 文件前 20 个字节

查看文件内容

命令:tail

参数说明:
-f: 循环读取
-q: 不显示处理信息
-v: 显示详细的处理信息
-c<数目>: 显示的字节数
-n<行数>: 显示文件的尾部 n 行内容

tail -f filename    # 会把 filename 文件里的最尾部的内容显示在屏幕上,并且不断刷新,只要 filename 更新就可以看到最新的文件内容。
tail notes.log         # 查看test.log末尾内容,默认显示最后 10 行
tail -c 10 notes.log    # 查看test.log最后 10 个字符

查找文件里符合条件的字符串或正则表达式

命令:grep

参数说明:
-i:忽略大小写进行匹配
-v:反向查找,只打印不匹配的行
-n:显示匹配行的行号
-r:递归查找子目录中的文件
-l:只打印匹配的文件名
-c:只打印匹配的行数

grep hello file.txt     # 在文件 file.txt 中查找字符串 "hello",并打印匹配的行
grep -r -n pattern dir/     # 在文件夹 dir 中递归查找所有文件中匹配正则表达式 "pattern" 的行,并打印匹配行所在的文件名和行号
grep -v test *test*     # 查找文件名中包含 test 的文件中不包含test 的行
grep [0-9] hello.txt    # 选择hello.txt⽂件中所有包含数字的⾏

文件/目录搜索

命令:find

find [路径] [匹配条件] [动作]

匹配条件 中可使用的选项有二三十个之多,以下列出最常用的部份:
-name pattern:按文件名查找,支持使用通配符 * 和 ?。
-type type:按文件类型查找,可以是 f(普通文件)、d(目录)、l(符号链接)等。
-size [+-]size[cwbkMG]:按文件大小查找,支持使用 + 或 - 表示大于或小于指定大小,单位可以是 c(字节)、w(字数)、b(块数)、k(KB)、M(MB)或 G(GB)。
-mtime days:按修改时间查找,支持使用 + 或 - 表示在指定天数前或后,days 是一个整数表示天数。
-user username:按文件所有者查找。
-group groupname:按文件所属组查找。
动作: 可选的,用于对匹配到的文件执行操作,比如删除、复制等。

find . -name file.txt   # 查找当前目录下名为 file.txt 的文件
find /home -size +1M    # 查找 /home 目录下大于 1MB 的文件
find /var/log -mtime +7     # 查找 /var/log 目录下在 7 天前修改过的文件
find /path/to/search -name "pattern" -exec rm {} \;     # 找并执行操作(例如删除)
find / -user user1      # 搜索用户 user1 的文件/目录

编辑文本文件

命令:vim

Vim 是从 vi 发展出来的一个文本编辑器。代码补全、编译及错误跳转等方便编程的功能特别丰富。 vim的高级使用较复杂,请参考其他文档学习。

设置环境变量

命令:export

以常见的两个环境变量:PATH和LD_LIBRARY_PATH为例
1. PATH
如果你有自己安装的命令,希望暴露出来直接使用。比如miniconda中的python,如果不加环境变量一般需要写完整的路径:/x/x/x/miniconda3/bin/python,如果希望直接写python就能用到调用conda中的python指令,那么可以:
export PATH=/x/x/x/miniconda3/bin:$PATH
先解释上述命令的格式,右侧的路径可以写多个,以:分隔,$PATH表示求PATH变量的值,因为PATH环境变量以前可能已经有值,需要保留那些值不影响其他命令的使用,其次当输入了python命令时,会从PATH变量的路径下去找python可执行文件,先找到哪个就用哪个,因此:前后路径的先后顺序也很重要。
2. LD_LIBRARY_PATH
和PATH路径一样,只不过LD_LIBRARY_PATH是设置动态链接库的搜索路径。比如安装了CUDA以后,一般需要设置:
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH

如果要查看是否设置成功可以使用命令:env | grep PATH 进行确认

最后以上设置的环境变量只在当前terminal的上下文中有效,如果希望全局有效,那么将export命令写入文件: ~/.bashrc,然后执行:source ~/.bashrc 生效或新打开终端

设置用户对文件的权限

命令:chmod

只有文件所有者和超级用户可以修改文件或目录的权限

chmod [-cfvR] [--help] [--version] mode file...

mode : 权限设定字串,格式如下 :
[ugoa...][[+-=][rwxX]...][,...]
其中:
u 表示该文件的拥有者,g 表示与该文件的拥有者属于同一个群体(group)者,o 表示其他以外的人,a 表示这三者皆是。
+ 表示增加权限、- 表示取消权限、= 表示唯一设定权限。
r 表示可读取,w 表示可写入,x 表示可执行,X 表示只有当该文件是个子目录或者该文件已经被设定过为可执行。
其他参数说明:
-c : 若该文件权限确实已经更改,才显示其更改动作
-f : 若该文件权限无法被更改也不要显示错误讯息
-v : 显示权限变更的详细资料
-R : 对目前目录下的所有文件与子目录进行相同的权限变更(即以递归的方式逐个变更)
--help : 显示辅助说明
--version : 显示版本
示例:
chmod ugo+r file1.txt       # 将文件 file1.txt 设为所有人皆可读取
chmod a+r file1.txt     # 将文件 file1.txt 设为所有人皆可读取
chmod u+x ex1.py        # 为 ex1.py 文件拥有者增加可执行权限
chmod -R a+r *      # 将目前目录下的所有文件与子目录皆设为任何人可读取 
chmod 777 file      # 此外chmod也可以用数字来表示权限,设置文件或目录的所有者、群组和其他用户都具有读、写和执行的权限

chmod abc file  
其中a,b,c各为一个数字,分别表示User、Group、及Other的权限。
r=4,w=2,x=1
若要 rwx 属性则 4+2+1=7;
若要 rw- 属性则 4+2=6;
若要 r-x 属性则 4+1=5

设置文件所有者和文件关联组

命令:chown

chown [-cfhvR] [--help] [--version] user[:group] file...

参数 :
user : 新的文件拥有者的使用者 ID
group : 新的文件拥有者的使用者组(group)
-c : 显示更改的部分的信息
-f : 忽略错误信息
-h :修复符号链接
-v : 显示详细的处理信息
-R : 处理指定目录以及其子目录下的所有文件
--help : 显示辅助说明
--version : 显示版本
示例:
chown root /var/run/test.py     # 把 /var/run/test.py 的所有者设置 root
chown test:testgroup file1.txt      # 将文件 file1.txt 的拥有者设为 test,群体的使用者testgroup 
chown -R test:testgroup *       # 将当前目录下的所有文件与子目录的拥有者皆设为 test,群体的使用者 testgroup
chown :512 /home/test     # 把 /home/test 的关联组设置为 512 (关联组ID),不改变所有者

设置文件或目录的所属群组

命令:chgrp

chgrp [-cfhRv][--help][--version][所属群组][文件或目录...]

参数说明
-c 或 --changes:效果类似"-v"参数,但仅回报更改的部分。
-f 或 --quiet 或 --silent:  不显示错误信息。
-h 或 --no-dereference:  只对符号连接的文件作修改,而不改动其他任何相关文件。
-R 或 --recursive:  递归处理,将指定目录下的所有文件及子目录一并处理。
-v 或 --verbose:  显示指令执行过程。
--help:  在线帮助。
--reference=<参考文件或目录>:  把指定文件或目录的所属群组全部设成和参考文件或目录的所属群组相同。
--version:  显示版本信息。
示例:改变文件的群组属性:
chgrp -v bin test.log
输出:
[root@localhost test]# ll
---xrw-r-- 1 root root 302108 11-13 06:03 test.log
[root@localhost test]# chgrp -v bin test.log
"test.log" 的所属组已更改为 bin
[root@localhost test]# ll
---xrw-r-- 1 root bin  302108 11-13 06:03 test.log

文件打包压缩、解压

命令:tar

对文件进行打包,默认情况并不会压缩,如果指定了相应的参数,它还会调用相应的压缩程序(如gzip和bzip等)进行压缩和解压

常用参数:
-c :新建打包文件
-t :查看打包文件的内容含有哪些文件名
-x :解打包或解压缩的功能,可以搭配-C(大写)指定解压的目录,注意-c,-t,-x不能同时出现在同一条命令中
-j :通过bzip2的支持进行压缩/解压缩
-z :通过gzip的支持进行压缩/解压缩
-v :在压缩/解压缩过程中,将正在处理的文件名显示出来
-f filename :filename为要处理的文件
-C dir :指定压缩/解压缩的目录dir
tar -cvf archive.tar file1 file2 directory      # 将文件file1、file2和directory打包到一个名为archive.tar的归档文件中
-c: 创建新的归档文件
-v: 显示详细输出,列出被添加到归档中的文件
-f: 指定归档文件的名称

tar -xvf archive.tar        # 解压名为archive.tar的归档文件,还原其中包含的文件和目录
-x: 解压归档文件
-v: 显示详细输出,列出被解压的文件
-f: 指定要解压的归档文件的名称

tar -zcvf archive.tar.gz directory      # 打包directory目录下的所有文件和子目录,并使用gzip压缩,生成名为archive.tar.gz的归档文件
-z: 表示要使用 gzip 进行压缩
-c: 表示创建新的归档文件。
-v: 表示详细输出,列出被添加到归档中的文件。
-f archive.tar.gz: 指定归档文件的名称为 archive.tar.gz

tar -zxvf example.tar.gz        # 解压一个已经被gzip压缩的归档文件:解压example.tar.gz文件,并在当前目录下恢复其中包含的文件和目录
-z: 表示要使用 gzip 解压归档文件。
-x: 表示解压操作。
-v: 表示详细输出,列出被解压的文件。
-f example.tar.gz: 指定要解压的归档文件的名称为example.tar.gz

查看进程的信息

命令:ps

常用参数:
-A:所有的进程均显示出来
-a:不与terminal有关的所有进程
-u:有效用户的相关进程
-x:一般与a参数一起使用,可列出较完整的信息
-l:较长,较详细地将PID的信息列出
ps -ef   # 显示所有进程的详细信息
ps aux  # 查看系统所有的进程数据
ps ax   # 查看不与terminal有关的所有进程
ps -lA  # 查看系统所有的进程数据
ps axjf    # 查看连同一部分进程树状态
pstree -aup  # 查看正在运行的树桩结构显示
netstat -lntp   # 查看各个节点及进程和使用的端口号

终止进程

命令:kill

kill -9 333  # 强制终止pid为333的进程,pid可通过ps命令获取

查看进程的CPU和内存占用

建议使用平台提供的实例监控功能查看

命令:top

top命令的显示信息:

top - 08:40:01 up 25 days,  2:28,  1 user,  load average: 0.76, 0.79, 0.65
Tasks:  11 total,   1 running,  10 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.1 us,  0.2 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem : 515592.8 total,  64588.2 free,  14906.2 used, 436098.3 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used. 497207.3 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     46 root      20   0   10.8g 593068 328880 S   0.3   0.1   0:06.90 tensorboard
    133 root      20   0   18.8g  10312   5744 S   0.3   0.0   0:00.21 server
    482 root      20   0    6116   3240   2720 R   0.3   0.0   0:00.01 top
      1 root      20   0    3984   3096   2820 S   0.0   0.0   0:00.06 entrypoint.sh
     37 root      20   0   33380  28564  10968 S   0.0   0.0   0:00.25 supervisord
     38 root      20   0 1240632  14824   8332 S   0.0   0.0   0:00.05 dashboard
     39 root      20   0  166736  82036  16416 S   0.0   0.0   0:01.26 jupyter-lab
     40 root      20   0 1241044  15312  10088 S   0.0   0.0   0:00.09 proxy
     41 root      20   0   12196   7068   6220 S   0.0   0.0   0:00.02 sshd
    448 root      20   0   12676   7884   6788 S   0.0   0.0   0:00.04 sshd
    460 root      20   0    4248   3624   3008 S   0.0   0.0   0:00.02 bash

PID:进程的标识符。
USER:运行进程的用户名。
PR(优先级):进程的优先级。
NI(Nice值):进程的优先级调整值。
VIRT(虚拟内存):进程使用的虚拟内存大小。
RES(常驻内存):进程实际使用的物理内存大小。
SHR(共享内存):进程共享的内存大小。
%CPU:进程占用 CPU 的使用率。
%MEM:进程占用内存的使用率。
TIME+:进程的累计 CPU 时间。

查看GPU信息

命令:nvidia-smi

Tue Aug 13 09:01:21 2024
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 550.90.07              Driver Version: 550.90.07      CUDA Version: 12.4     |
|-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA GeForce RTX 4090        Off |   00000000:98:00.0 Off |                  Off |
|  0%   26C    P8              9W /  450W |       4MiB /  24564MiB |      0%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+

+-----------------------------------------------------------------------------------------+
| Processes:                                                                              |
|  GPU   GI   CI        PID   Type   Process name                              GPU Memory |
|        ID   ID                                                               Usage      |
|=========================================================================================|
|  No running processes found                                                             |
+-----------------------------------------------------------------------------------------+

常见使用场景

场景1:发现程序停止了,但是显存还在占用

一般这种情况是进程假死,看上去停止了但是实际还在。可以通过ps -ef查看进程是否还存在,如果存在则用kill命令杀死进程,最后用nvidia-smi检查显存是否已经释放。

场景2:发现进程内存会使用超过限制,导致进程被Killed

可以使用Top命令查看进程的占用内存情况,确认内存是不是会停留在一个值而不会一直增长,如果一直增长说明程序对内存的释放有漏洞,可以分析Python代码变量的引用来进行优化。

场景3:使用JupyerLab的终端挂守护进程跑训练,担心关闭网页期间的日志看不到了

可以使用重定向日志功能,把日志写入文件 使用>命令

user@host:/root# python train.py > ./train.log  # 把训练产生的日志重定向到train.log文件中,
user@host:/root# cat ./train.log    # 查看日志内容
Epoch.1 Iter 20
Epoch.1 Iter 40
Epoch.1 Iter 50
...