L0G1-Linux 基础知识
L0G1-Linux基础知识
1. 闯关任务
1.1 任务内容
完成SSH连接与端口映射并运行hello_world.py
1.2 任务步骤
1.2.1 创建开发机
选择的镜像和资源配置如下,并点击“立即创建”。
等待大约5分钟后,开发机创建成功,并开始运行:
1.2.2 用vscode连接到开发机
-
点击“SSH连接”
-
拷贝ssh命令
ssh -p 49483 root@ssh.intern-ai.org.cn -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
-
在vscode中启动插件,点击“添加新的ssh主机”,并输入ssh命令。之后拷贝密码,同样输入即可连接成功。
-
点击“打开文件夹”,选择
/root/
并确定,进入开发机的/root/
目录下 -
配置SSH密钥进行SSH远程连接
在我们开发学习的时候,每次远程都输入密码比较麻烦,我们可以设置SSH key来跳过输入密码这一步骤,在ssh命令中我们可以使用ssh-keygen命令来生成密钥
ssh-keygen支持RSA和DSA两种认证密钥。
常用参数包括:
- -t:指定密钥类型,如dsa、ecdsa、ed25519、rsa。
- -b:指定密钥长度。
- -C:添加注释。
- -f:指定保存密钥的文件名。
- -i:读取未加密的ssh-v2兼容的私钥/公钥文件。
运行
ssh-keygen -t rsa
生成密钥,windows系统下生成的密钥默认在C:\Users\{your_username}\.ssh\
下。生成的公钥和私钥如下图所示:
-
拷贝公钥的内容到平台上,完成ssh-key的配置。如下图:
-
打开vscode的远程连接就可以看到第一次连接的开发机信息,下面的
root
代表我们第一连接开发机时使用的是/root
工作目录。点击下图中的->
即可进入上一次的/root
目录,这次不需要密码。也可以点击下图的
->
重新选择工作目录,同样不需要密码。
1.2.3 创建hello_world.py并安装依赖
-
创建文件如下:
-
使用
pip install gradio==4.29.0
安装运行文件需要的依赖
1.2.4 进行端口转发
1. 为什么要进行端口转发?
当在开发机中运行hello_world.py
后,会在开发机的7860端口启动一个gradio服务,展示一个网页。但开发机没有浏览器,所以不能查看网页。我们可以实现这样一件事:在本地机器的浏览器中输入127.0.0.1:7860
,这个命令是访问本地机器的7860端口的服务的。而通过端口转发,让浏览器认为自己访问的是本地机器的 127.0.0.1:7860
,但实际上数据是从开发机的7860端口获取的!
流程如下:
- 浏览器访问本地机器的
127.0.0.1:7860
- 本地 SSH 端口转发机制会拦截这个请求(流量)。
- 通过 SSH 隧道,这个请求(流量)被转发到开发机器的
127.0.0.1:7860
端口。 - 运行在开发机器
127.0.0.1:7860
端口的 Gradio 服务器处理请求并返回网页数据。 - 返回的数据通过 SSH 隧道传输回本地机器,并最终展示在浏览器中。
2. 如何实现端口转发
前面我们已经SSH远程连接了开发机,VScode提供了自动端口映射的功能,不需要自己配置,直接在vscode的终端中运行python文件即可在本地浏览器中访问网页。
在这里可以查看端口映射的信息,如果需要修改端口的话,可以在端口那一栏修改端口号。
也可以在开发机的自定义服务中获取到端口转发的ssh命令,在本地机器上运行。
选项 | 方向 | 适用场景 |
---|---|---|
-L (本地端口转发) |
本地 → 远程 | 访问远程服务器的服务,如 Jupyter Notebook、Gradio |
-R (远程端口转发) |
远程 → 本地 | 让远程服务器访问你本地的服务,如 SSH 反向代理 |
2. 可选任务 1
2.1 任务内容
将Linux基础命令在开发机上完成一遍
2.2 任务步骤
2.2.1 cp命令
cp [选项] 源文件 目标文件 cp [选项] 源文件 目标目录/ cp [选项] -r 源目录 目标目录/
cp file1.txt file2.txt # 将 file1.txt 复制为 file2.txt(如果 file2.txt 存在,则会覆盖) cp file1.txt /home/user/Documents/ # 将 file1.txt 复制到 /home/user/Documents/ 目录下,文件名不变。 cp file1.txt file2.txt file3.txt /home/user/Documents/ # 将 file1.txt、file2.txt、file3.txt 复制到 /home/user/Documents/。 cp -r myfolder/ backup/ # 复制 myfolder 目录及其所有内容到 backup/ 目录。
注意点: cp命令在复制符号链接时默认会复制链接指向的文件,而不是链接本身。
要实现一个软链接复制到另一个目录下仍然是软链接且有效,需要两个条件:
- 该软链接在创建时,源路径使用的是绝对路径。
- 因为软链接的文件内容是告诉系统怎么从软链接所在目录访问到源文件,如果是相对路径的话,软链接的位置一旦改变就会失效。
- 拷贝的命令必须加上
--preserve=links -r
,这两个选项缺一不可。
2.2.2 ln命令
ln [参数][源文件或目录][目标文件或目录] ln a b # 创建b为a的硬链接(默认行为) ln -s a b # 创建b为a的软链接,注意,这里的a是相对路径时,不是相对于当前目录的路径,而是相对于b的路径,即要告诉系统怎么从b找到a
Linux 链接分两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link)。默认情况下,ln 命令产生硬链接。
硬连接——保护重要文件
硬连接指通过索引节点来进行连接。在 Linux 的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号(Inode Index)。在 Linux 中,多个文件名指向同一索引节点是存在的。比如:A 是 B 的硬链接(A 和 B 都是文件名),则 A 的目录项中的 inode 节点号与 B 的目录项中的 inode 节点号相同,即一个 inode 节点对应两个不同的文件名,两个文件名指向同一个文件,A 和 B 对文件系统来说是完全平等的。删除其中任何一个都不会影响另外一个的访问。
硬连接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬连接到重要文件,以防止“误删”的功能。其原因如上所述,因为对应该目录的索引节点有一个以上的连接。只删除一个连接并不影响索引节点本身和其它的连接,只有当最后一个连接被删除后,文件的数据块及目录的连接才会被释放。也就是说,文件真正删除的条件是与之相关的所有硬连接文件均被删除。
软连接——创建快捷方式,方便在不同的目录下快捷地访问某个文件,而不需要拷贝多份,节省空间
另外一种连接称之为符号连接(Symbolic Link),也叫软连接。软链接文件有类似于 Windows 的快捷方式。它实际上是一个特殊的文件。在符号连接中,文件实际上是一个文本文件,其中包含的有另一文件的位置信息。比如:A 是 B 的软链接(A 和 B 都是文件名),A 的目录项中的 inode 节点号与 B 的目录项中的 inode 节点号不相同,A 和 B 指向的是两个不同的 inode,继而指向两块不同的数据块。但是 A 的数据块中存放的只是 B 的路径名(可以根据这个找到 B 的目录项)。A 和 B 之间是“主从”关系,如果 B 被删除了,A 仍然存在(因为两个是不同的文件),但指向的是一个无效的链接。
从上面的结果中可以看出,硬连接文件 f2 与原文件 f1 的 inode 节点相同,均为 9797648,然而符号连接文件的 inode 节点不同。
当删除原始文件 f1 后,硬连接 f2 不受影响,f1文件对应的数据块还能通过f2访问到,但是符号连接 f3 文件无效
2.2.3 sed命令
sed
(Stream Editor,流编辑器)是一个强大的文本处理工具,可以用于查找、替换、删除、插入、修改文件内容,且可以批量处理数据,适用于自动化文本处理任务。
-
sed
基本语法sed [选项] '命令' 文件名
命令
:对文本执行的操作(如替换、删除、插入等)。文件名
:要操作的文件(如果不指定,则从标准输入读取数据)。sed
处理文件的方式是一行一行处理,所以每个动作的效果都是对一行来说的。- 参数说明:
-e<script>
或--expression=<script>
:直接在命令行中指定脚本进行文本处理。默认参数,单个命令时可以不写,当使用多个sed
命令时,必须用-e
明确区分不同命令。-f<script文件>
或--file=<script文件>
:从指定的脚本文件中读取脚本进行文本处理。-n
或--quiet
或--silent
:仅打印经过脚本处理后的输出结果,不打印未匹配的行。-i
:sed
命令默认将修改后的内容打印到终端,该选项表示直接修改文件内容。不用该选项时可以用>
将打印的内容重定向到新文件中。-i.bak
可以实现备份原文件再修改。
- 动作说明:
a
:在当前行的下一行添加指定的文本字符串。c
:用指定的文本字符串替换指定范围内的行。d
:删除指定的行。i
:在当前行的上一行添加指定的文本字符串。p
:打印经过选择的行。通常与-n
参数一起使用,只打印匹配的行。s
:进行文本替换。例如,s/old/new/g
将所有 "InternLM" 替换为 "InternLM yyds"。//
:使用//
进行匹配时,默认就是正则表达式s///
是替换命令(substitute),用于搜索并替换文本。//
本身只是匹配模式,但不能单独使用,需要结合d
(删除)、p
(打印)等命令。
n1,n2
:对n1~n2行操作
-
sed
常用操作1)替换文本
基本替换
sed 's/old/new/' file.txt
🔹 作用:将
file.txt
中的每行的第一处old
替换为new
(每行只替换一次,而不是整个文件只替换一次)。全局替换(替换每行所有匹配项)
sed 's/old/new/g' file.txt
🔹 作用:将
file.txt
中的所有old
替换为new
。忽略大小写替换
sed 's/old/new/gi' file.txt
🔹 作用:大小写不敏感替换
old
为new
。修改原文件(
-i
选项)sed -i 's/old/new/g' file.txt
🔹 作用:直接修改
file.txt
文件,不会输出到终端。
2)删除行
删除第 3 行
sed '3d' file.txt
🔹 作用:删除
file.txt
的第 3 行。删除第 2 到 4 行
sed '2,4d' file.txt
🔹 作用:删除
file.txt
的第 2、3、4 行。删除包含 "abc" 的行
sed '/abc/d' file.txt
🔹 作用:删除所有包含
abc
的行。
3)插入和追加行
在第 2 行前插入一行
sed '2i\This is a new line' file.txt
🔹 作用:在第 2 行之前插入
This is a new line
。在第 3 行后追加一行
sed '3a\Added after line 3' file.txt
🔹 作用:在第 3 行之后追加
Added after line 3
。
4)提取/显示特定行
显示第 2 到 4 行
sed -n '2,4p' file.txt
🔹 作用:只打印
file.txt
的第 2、3、4 行。显示包含 "hello" 的行
sed -n '/hello/p' file.txt
🔹 作用:只打印包含 "hello" 的行。
5)替换文本中的
&
&
代表原匹配内容,可用于添加前缀、后缀:echo "Hello" | sed 's/Hello/& World/'
🔹 输出:
Hello World
✅ "&" 代表被匹配到的
Hello
,替换后变成Hello World
。
-
sed
进阶用法1)使用多个
sed
命令可以用
-e
运行多个sed
命令:sed -e 's/foo/bar/g' -e 's/hello/world/g' file.txt
🔹 作用:先将
foo
替换为bar
,再将hello
替换为world
。
2)删除空行
sed '/^$/d' file.txt
🔹 作用:删除所有空行。
3)使用
&
进行替换为数字添加
¥
符号echo "Price: 100" | sed 's/[0-9]\+/¥&/'
🔹 输出:
Price: ¥100
✅
&
代表匹配到的数字,替换后变成¥100
。
4)只替换某一行
sed '3s/old/new/g' file.txt
🔹 作用:仅替换第 3 行的
old
为new
。
5)备份原文件再修改
sed -i.bak 's/old/new/g' file.txt
🔹 作用:修改
file.txt
并创建file.txt.bak
备份文件。 -
练习记录
3. 可选任务2
3.1 任务内容
使用 VSCODE 远程连接开发机并创建一个conda环境
3.2 任务步骤
3.2.1 创建虚拟环境
conda create -n test python=3.10
创建结果:
3.2.2 激活与退出虚拟环境
激活虚拟环境:
退出虚拟环境:
3.2.3 导出虚拟环境
3.2.4 删除虚拟环境
知识积累
StrictHostKeyChecking no和UserKnownHostsFile /dev/null的作用
以下内容来自chatgpt:
StrictHostKeyChecking no UserKnownHostsFile /dev/null 这两条配置的作用
1️⃣
StrictHostKeyChecking no
作用:禁用 SSH 主机密钥检查。
当客户端首次连接到一个新的 SSH 服务器时,SSH 会提示你确认该服务器的公钥(Host Key)。默认情况下,它会要求你输入
yes
或
no
来确认主机身份:
The authenticity of host '192.168.1.10 (192.168.1.10)' can't be established. ECDSA key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxx. Are you sure you want to continue connecting (yes/no)?
如果设置
StrictHostKeyChecking no
,SSH 不会再询问,而是自动接受所有主机密钥,即使主机密钥发生变化也不会警告。适用场景:
- 在自动化脚本(如
scp
、rsync
、Ansible
远程部署)中,避免人工确认提示。- 适用于临时连接,但有安全风险,容易遭受 中间人攻击(MITM)。
配置方式:
在
~/.ssh/config
中添加:
Host * StrictHostKeyChecking no
直接在命令行使用:
ssh -o StrictHostKeyChecking=no user@server
2️⃣
UserKnownHostsFile /dev/null
作用:不保存远程主机密钥。
SSH 默认会将连接过的远程主机的公钥存储在
~/.ssh/known_hosts
文件中,以便下次连接时检查是否发生了密钥变更。如果设置
UserKnownHostsFile /dev/null
,SSH 不会在本地保存已连接主机的公钥,并且 不会检查已知主机列表。适用场景:
- 避免
known_hosts
文件不断增长,尤其是在大规模自动化环境中(如 CI/CD、云服务器自动化管理)。- 在环境重置频繁的情况下(如动态创建和销毁的 Docker 容器),不保存主机密钥以避免
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
错误。配置方式:
在
~/.ssh/config
中添加:
Host * UserKnownHostsFile /dev/null
直接在命令行使用:
ssh -o UserKnownHostsFile=/dev/null user@server
🚨 安全风险
这两项配置降低了 SSH 连接的安全性,适用于自动化脚本,但可能带来安全隐患:
- 可能遭受 MITM(中间人攻击):
- 因为 SSH 不会检查主机密钥的变化,如果攻击者劫持了连接并伪装成目标服务器,你不会收到任何警告。
- 主机密钥更改不会被检测:
- 在正常情况下,如果服务器的 SSH 主机密钥变更,SSH 会警告你可能遭受攻击,但这两个选项会直接忽略这种检查。
如果是生产环境,建议不要全局使用,可以在临时任务或受信任环境中使用。
nvidia-smi输出的GPU信息解读
tmux操作
首先要按照如下步骤配置tmux再根据指南操作(因为有一些自定义的按键)
-
创建配置文件,在 tmux 里用 vim
https://superuser.com/questions/1325629/unknown-command-error-when-loading-tmux-conf
tmux show -g | sed 's/^/set -g /' > ~/.tmux.conf
-
修改配置文件,主要修改前缀键和开启鼠标
vim .tmux.conf
-
acwing 的 tmux 配置
set-option -g status-keys vi setw -g mode-keys vi setw -g monitor-activity on # setw -g c0-change-trigger 10 # setw -g c0-change-interval 100 # setw -g c0-change-interval 50 # setw -g c0-change-trigger 75 set-window-option -g automatic-rename on set-option -g set-titles on set -g history-limit 100000 #set-window-option -g utf8 on # set command prefix set-option -g prefix C-a unbind-key C-b bind-key C-a send-prefix bind h select-pane -L bind j select-pane -D bind k select-pane -U bind l select-pane -R bind -n M-Left select-pane -L bind -n M-Right select-pane -R bind -n M-Up select-pane -U bind -n M-Down select-pane -D bind < resize-pane -L 7 bind > resize-pane -R 7 bind - resize-pane -D 7 bind + resize-pane -U 7 bind-key -n M-l next-window bind-key -n M-h previous-window set -g status-interval 1 # status bar set -g status-bg black set -g status-fg blue #set -g status-utf8 on set -g status-justify centre set -g status-bg default set -g status-left " #[fg=green]#S@#H #[default]" set -g status-left-length 20 # mouse support # for tmux 2.1 # set -g mouse-utf8 on set -g mouse on # # for previous version #set -g mode-mouse on #set -g mouse-resize-pane on #set -g mouse-select-pane on #set -g mouse-select-window on #set -g status-right-length 25 set -g status-right "#[fg=green]%H:%M:%S #[fg=magenta]%a %m-%d #[default]" # fix for tmux 1.9 bind '"' split-window -vc "#{pane_current_path}" bind '%' split-window -hc "#{pane_current_path}" bind 'c' new-window -c "#{pane_current_path}" # run-shell "powerline-daemon -q" # vim: ft=conf
功能:
(1) 分屏。
(2) 允许断开Terminal连接后,继续运行进程。
结构:
一个tmux可以包含多个session,一个session可以包含多个window,一个window可以包含多个pane。
实例:
tmux:
session 0:
window 0:
pane 0
pane 1
pane 2
...
window 1
window 2
...
session 1
session 2
...
操作:
(1) tmux:新建一个session,其中包含一个window,window中包含一个pane,pane里打开了一个shell对话框。
(2) 按下Ctrl + a后手指松开,然后按%:将当前pane左右平分成两个pane。
(3) 按下Ctrl + a后手指松开,然后按"(注意是双引号"):将当前pane上下平分成两个pane。
(4) Ctrl + d:关闭当前pane;如果当前window的所有pane均已关闭,则自动关闭window;如果当前session的所有window均已关闭,则自动关闭session。
(5) 鼠标点击可以选pane。
(6) 按下ctrl + a后手指松开,然后按方向键:选择相邻的pane。
(7) 鼠标拖动pane之间的分割线,可以调整分割线的位置。
(8) 按住ctrl + a的同时按方向键,可以调整pane之间分割线的位置。
(9) 按下ctrl + a后手指松开,然后按z:将当前pane全屏/取消全屏。
(10) 按下ctrl + a后手指松开,然后按d:挂起当前session。
(11) tmux a:打开之前挂起的session。
(12) 按下ctrl + a后手指松开,然后按s:选择其它session。
方向键 —— 上:选择上一项 session/window/pane
方向键 —— 下:选择下一项 session/window/pane
方向键 —— 右:展开当前项 session/window
方向键 —— 左:闭合当前项 session/window
(13) 按下Ctrl + a后手指松开,然后按c:在当前session中创建一个新的window。
(14) 按下Ctrl + a后手指松开,然后按w:选择其他window,操作方法与(12)完全相同。
(15) 按下Ctrl + a后手指松开,然后按PageUp:翻阅当前pane内的内容。
(16) 鼠标滚轮:翻阅当前pane内的内容。
(17) 在tmux中选中文本时,需要按住shift键。(仅支持Windows和Linux,不支持Mac,不过该操作并不是必须的,因此影响不大)
(18) tmux中复制/粘贴文本的通用方式:
(1) 按下Ctrl + a后松开手指,然后按[
(2) 用鼠标选中文本,被选中的文本会被自动复制到tmux的剪贴板
(3) 按下Ctrl + a后松开手指,然后按],会将剪贴板中的内容粘贴到光标处
&> /dev/null 作用
某个命令 &> /dev/null
&>
是 Bash 中的重定向操作符,表示同时重定向 标准输出(stdout) 和 标准错误(stderr)。/dev/null
是一个特殊设备,表示“丢弃”输出,因此 无论命令成功还是失败,都不会在终端显示输出。