跳转至

Linux开发环境基础知识

1. 如何登陆Linux

登录Linux系统通常有几种不同的方法:

1.1 使用VSCode登录

  • 首先,确保你已经安装了Visual Studio Code(VSCode)。
  • 然后,你需要安装Remote - SSH扩展。
  • 配置SSH连接,通常需要服务器的IP地址、用户名和可能的SSH密钥。
  • 使用VSCode打开一个新的SSH终端,连接到远程服务器。

使用VSCode登录远程实验平台具体步骤详见远程实验环境使用指南

1.2 使用MobaXterm登录

具体步骤详见MobaXterm工具

1.3 在本地电脑上启动Linux

  • 如果你使用的是虚拟机,如VirtualBox或VMware,启动虚拟机并按照引导进行登录。
  • 如果你使用的是Windows Subsystem for Linux (WSL),可以通过Windows的开始菜单搜索并启动WSL,然后输入用户名和密码进行登录。

2. 常用文件管理命令

2.1 Linux文件管理

Linux文件路径的描述本质上是一棵树,目录和文件就是树中的各种节点。

根目录 / : 根目录是文件系统这棵树的根节点。通过 cd / 命令进入根目录,输入 ls 并回车,可以看到以下文件夹:

  • bin :存储常用可执行文件的命令
  • etc :代理服务器的配置文件
  • var :里面会有log(日志)
  • lib :安装包和库文件(静态连接库)等
  • home :用户的家目录
  • proc :进程相关的信息,计算机信息
  • ……

2.2 Linux路径描述

执行 cd ~ 命令回到家目录,执行以下命令:

cd ~
mkdir tmp
touch tmp/main.cpp

如何描述这个 main.cpp 文件的路径呢?Linux里有两种方式:

  • 绝对路径 :从根目录开始描述路径。main.cpp 的绝对路径描述是 /home/学号/tmp/main.cpp
    • 绝对路径的描述一定以根目录 / 开头。
  • 相对路径 :从当前目录开始描述路径。main.cpp 的相对路径描述是 tmp/main.cpp

大家可以随时通过 pwd 命令查看当前路径,pwd 命令的输出是当前命令的绝对路径描述。

在路径描述里,Linux有三个特殊目录:

  • . 目录 :表示当前目录。执行 cd . 不会改变当前路径。
  • .. 目录 :表示上一级目录。
    • 大家执行 cd tmp 进入 tmp 文件夹,再执行 cd .. 就回到上一级的家目录了。
  • ~ 目录 : 家目录,不论在哪个目录下,只要执行 cd ~ 就会回到家目录。
    • 描述家目录下的 tmp 文件夹也可以用 ~/tmp 来描述。

2.3 常用命令介绍

  • ctrl + c : 用于中止当前正在执行的进程。
    • 大家可以执行 top 命令,该命令会启动一个进程并展示当前运行的进程信息。之后使用 ctrl + c 就可以退出 top 的进程。
    • 其他进程同理,都可以在终端使用 ctrl + c 进行中止。
  • ctrl + u: 清空本行命令。
  • tab键:可以补全命令和文件名,如果补全不了快速按两下tab键,可以显示备选选项。
  • 方向键 ↑ 可以调出历史指令。
  • ls : 列出当前目录下所有文件,蓝色的是文件夹,白色的是普通文件,绿色的是可执行文件(具体颜色可能因系统配置而异)。
    • ls -l : 以列表形式展示详细信息,包括文件权限、所有者、大小等。
    • ls -hl : 结合-h(人性化显示文件大小)和-l,使文件大小更易于阅读(如以KB、MB为单位)。
    • -a : 查询所有文件(包括隐藏文件)(所有以.开头的文件都是隐藏文件)。
  • pwd: 显示当前工作目录的完整路径。
  • cd: 更改当前工作目录。
    • cd 目录路径: 切换到指定目录路径。
    • cd : 不加路径则返回家目录。
    • cd - : 返回上一个待过的路径。
    • cd .. 返回上层目录。
  • cp: 复制文件或目录。
    • cp 文件1 文件2 : 将文件1复制到同一目录下并命名为文件2。
    • cp -r a b : 将目录a及其内容递归复制到目录b中(如果b不存在,则会被创建)。
  • mkdir: 创建新目录
    • mkdir 目录名 : 创建单个目录。
    • mkdir g\ s: 创建包含空格的目录(如'g s'),需使用反斜杠\进行转义。
    • mkdir -p a/b/c : 一次性创建多级目录(若a或b不存在,则一并创建)。
  • rm : 删除文件或目录。;
    • rm 文件名: 删除指定的文件。
    • rm -r 目录名: 递归删除整个目录及其内容。
    • rm -f 文件名: 强制删除文件,不提示确认。这个参数具有一定危险性,使用之前请先询问老师和助教。
  • mv: 移动或重命名文件/目录。
    • mv 文件名 目录 : 将文件移动到对应目录里。
    • mv a.txt b.txt : 将 a.txt 重命名为 b.txt
  • touch 文件名 : 创建一个空文件或更新现有文件的时间戳。
  • cat 文件名 : 查看文件内容,将文件内容输出到标准输出(通常是终端)。

3 开发常用命令

  Linux命令非常多,本节讲解几个常用命令。其他命令依赖于大家根据实际操作环境,边用边查。

  不会使用某个命令,可以用 man 命令命令 --help 来查看命令说明。

3.1 系统状况

  1. top :查看所有进程的信息(Linux的任务管理器)。
    • 打开后,输入 M :按使用内存排序。
    • 打开后,输入 P :按使用CPU排序。
    • 打开后,输入 q :退出。
  2. df -h :查看硬盘使用情况。
  3. free -h :查看内存使用情况。
  4. du -sh :查看当前目录占用的硬盘空间。
  5. ps aux :查看所有进程。
  6. kill -9 pid :杀死编号为 pid 的进程。
    • 传递某个具体的信号: kill -s SIGTERM pid(某些程序必须要用term结束而不能杀死,因此关闭某个程序最好先查文档看应该怎么关)。
    • 9SIGKILL 信号的编号, SIGTERM 的编号是 15
    • kill表示杀死进程,term表示正常结束一个进程。
  7. netstat -nt :查看所有网络连接。
  8. w :列出当前登陆的用户。
  9. ping www.baidu.com :检查是否连网。
    • Linux上的ping命令是不会自动终止的,需要使用Ctrl + c终止。

3.2 文件权限

  1. chmod :修改文件权限。
    • chmod +x 文件名 :给文件添加可执行权限。
      • 执行这个文件程序:./文件路径 (如果文件在当前目录下,则 ./文件名)。
    • chmod -x 文件名 :去掉文件的可执行权限。
    • chmod 777 文件名 :将文件名的权限改成777。
      • 三位数,每一位对应一组的权限。每位数字取值0~7,转化成二进制就是三位,每一位上,1表示有权限,0表示无权限。
    • chmod 777 目录名 -R :递归修改整个文件夹的权限。
    • 补充:文件的权限表示有10位。
      • 第一位表示是否是文件夹或超链接(快捷方式)。
      • 后9位按序每三位一组。
      • 三位中从前往后分别表示可读权限,可写权限,可执行权限。
      • 三组从前往后分别表示自己的权限,同组用户的权限,其他用户的权限。
      • 举例:在终端输入 ls -l ,可以看到所有文件的权限。假设在家目录下有一个 main.sh 脚本文件,它的权限是 -rw-r--r-- ,则
        • 第1位是 - ,表示是普通文件。
        • 第2到4位是 rw- , 表示这个文件用户自己可以读和写,但是不能执行。
        • 第5到7位是 r-- , 表示这个文件,同组的其他用户只能读,不能写和执行。
        • 第8到10位是 r-- , 表示这个文件,系统里的其他用户只能读,不能写和执行。
        • 如果执行 chmod +x main.sh , 则权限第4位会变为 x ,表示这个文件可以执行。
        • 在家目录下执行 main.sh , 使用 ./main.sh 命令即可。

3.3 文件检索

  1. find 目录路径 -name '*.c' :搜索某个文件路径下的所有后缀为.c的文件。
  2. grep xxx :从 标准输入(stdin) 中读入若干行数据,如果某行中包含 xxx ,则输出该行;否则忽略该行。
    • grep XXX 文件名或正则表达式 :查找名称匹配文件名或正则表达式的文件里,有没有XXX字符串。
  3. wc :统计行数、单词数、字节数。
    • 既可以从 stdin 中直接读入内容;也可以在命令行参数中传入文件名列表。
    • wc 文件名 按序输出行数、单词数,字节数。
    • wc -l :统计行数。
    • wc -w :统计单词数。
    • wc -c :统计字节数。
  4. cut :分割一行内容。
    • stdin 中读入多行数据。
    • echo $PATH | cut -d ':' -f 3,5 :输出 PATH: 分割后第3、5列数据。
    • echo $PATH | cut -d ':' -f 3-5 :输出 PATH: 分割后第3-5列数据。
    • echo $PATH | cut -c 3,5 :输出 PATH 的第3、5个字符。
    • echo $PATH | cut -c 3-5 :输出 PATH 的第3-5个字符。
  5. sort :将每行内容按字典序排序。
    • 可以从 stdin 中读取多行数据。
    • 可以从命令行参数中读取文件名列表。
  6. xargs :将 stdin 中的数据用空格或回车分割成命令行参数。
    • find . -name '*.c' | xargs cat | wc -l :统计当前目录下所有c文件的总行数。
    • 如果不加 xargs 也会有输出,但是这个输出统计的不是 .c 文件。不加 xargs , cat 输出的就是 stdin 文件的内容,统计的也就是 stdin 的行数。

3.4 查看文件内容

  1. more 文件名 :浏览文件内容。
    • 回车:下一行。
    • 空格:下一页。
    • b :上一页。
    • q :退出。
  2. less 文件名 :与 more 类似,功能更全。
    • 回车:下一行。
    • y :上一行。
    • Page Down :下一页。
    • Page Up :上一页。
    • q :退出。
  3. head -3 文件名 :展示文件的前3行内容。
    • 同时支持从 stdin 读入内容。
  4. tail -3 文件名 :展示文件末尾3行内容。
    • 同时支持从 stdin 读入内容。

3.5 用户相关

  1. history :展示当前用户的历史操作。内容存放在 ~/.bash_history 中。
    • history 展示的历史操作包含当前bash界面用户使用过的后2000条操作,而 .bash_history 里的历史操作不包含当前未关闭的bash里的操作。只有关闭bash之后,才会把操作写入 .bash_history 文件。

3.6 工具

  1. md5sum 文件名 :计算 md5 哈希值。
    • 计算任意长度的字符串的哈希值。
    • 可以从 stdin 读入内容。
    • 也可以在命令行参数中传入文件名列表。
    • 一般计算文件的哈希值,用于核对文件是否准确且完好无损。
    • 也可以用于加密信息,比如加密密码。
      • 数据库存储密码时都不会存储原密码字符串,而是存储密码的哈希值。哈希值几乎不可能反推。用户输入密码后,先转化成哈希值再比对。所以如果忘记密码就只能重设密码,而不能找回密码。
  2. time 命令 :统计命令的执行时间。
  3. watch -n 0.1 命令 :每0.1秒执行一次命令。
  4. tar :压缩文件。
    • tar -zcvf 压缩文件名.tar.gz 目录路径/* :将目标文件夹下所有文件压缩为 .tar.gz 类型文件。
    • tar -zxvf 压缩文件名.tar.gz :解压缩。
  5. diff 文件名1 文件名2 :查找文件的不同点。

3.7 查看系统信息

  • 查看系统信息:cat /etc/os-release
  • 查看 CPU 信息:lscpu
  • 查看内存信息:free
  • 查看磁盘信息:fdisk -l
  • 显示当前的日期和本地时间:date
  • 显示当前的日期和 UTC 时间:date --utc/--u

4 Linux管道和重定向

4.1 管道命令要点

  管道(Pipeline)是Unix/Linux系统中的一个强大特性,它允许将一个命令的输出(stdout)直接作为另一个命令的输入(stdin),从而实现命令之间的数据传递和连续处理

  1. 管道命令仅处理标准输出(stdout),会忽略标准错误输出(stderr) 。
  2. 管道右边的命令必须能接受标准输入(stdin)。
  3. 多个管道命令可以串联使用。

4.2 管道命令举例

  以下是一个使用管道命令的实例,旨在统计当前目录及其子目录下所有C语言文件的总行数。这个示例结合了findxargscatwc命令的功能:

  大家可以在实验目录xv6-oslab24-hitsz下执行以下命令(注意切换到除了main以外的分支,比如执行 git checkout util)

find . -name '*.c' | xargs cat | wc -l
  • find:该命令用于在当前目录(.)及其子目录下查找所有扩展名为.c的文件。其输出是每个找到的文件的路径。
  • xargs:xargs命令读取find命令的输出(即文件路径),并将这些路径作为参数传递给cat命令。注意,这里使用xargs是为了处理文件名中可能包含的特殊字符或空格的情况。
  • cat:cat命令读取xargs传递的文件路径,并将文件内容输出到标准输出(stdout)。由于管道的作用,cat的输出成为下一个命令wc的输入。
  • wc -l:wc命令用于统计字数、字节数等,-l选项指定仅统计行数。它读取cat命令的输出(即所有C语言文件的内容),并统计这些内容的总行数,最终输出结果。

4.3 重定向

在 Unix/Linux 系统中,重定向是一个非常强大的功能,它允许用户将命令的输入、输出或错误输出重定向到文件或其他命令中。

4.3.1 基本概念

  • 标准输入(stdin) :文件描述符为0,Unix/Linux程序默认从stdin读取数据。在终端中,stdin通常连接到键盘。
  • 标准输出(stdout):文件描述符为1,Unix/Linux程序默认向stdout输出数据。在终端中,stdout通常显示在屏幕上。
  • 标准错误(stderr):文件描述符为2,Unix/Linux程序会向stderr流中写入错误信息。在终端中,stderr也显示在屏幕上,但与stdout分开。

4.3.2 输出重定向

  • 基本输出重定向

    • command > file:将命令的标准输出重定向到file中。如果file已存在,则覆盖其内容;如果file不存在,则创建该文件。
    • command >> file:将命令的标准输出以追加的方式重定向到file中。如果file已存在,则在文件末尾添加内容;如果file不存在,则创建该文件。
  • 标准错误重定向

    • command 2> file:将命令的标准错误重定向到file中。注意,这里2>与文件名之间没有空格。
    • command 2>> file:将命令的标准错误以追加的方式重定向到file中。
  • 同时重定向标准输出和标准错误

    • command > file 2>&1:首先,将标准输出重定向到file中;然后,将标准错误重定向到标准输出当前指向的位置(即file)。这种方法在旧版本的shell中常用。
    • command &> file:这是现代shell(如bash)提供的一种更简洁的语法,同时重定向标准输出和标准错误到file中。

4.3.3 输入重定向

  • command < file:将命令的标准输入重定向到file中。这样,命令就会从file中读取输入数据,而不是从键盘读取。

4.3.4 其他重定向用法

  • 使用文件描述符进行重定向

    • n > file:将文件描述符n的输出重定向到file中。这里n可以是0(stdin)、1(stdout)或2(stderr)之外的任何文件描述符,但通常用于自定义的文件描述符。
    • n >> file:将文件描述符n的输出以追加的方式重定向到file中。
    • n >& m:将文件描述符n的输出重定向到文件描述符m的当前位置。这通常用于合并不同来源的输出。
    • n <& m:将文件描述符n的输入重定向到文件描述符m的当前位置。这较少使用,因为输入重定向通常直接通过<符号完成。
  • Here Document(内嵌文档)

    • << delimiter:将开始标记delimiter和结束标记delimiter之间的内容作为输入传递给命令。这种方式允许直接在命令行中提供多行输入。

重定向注意事项

  • 在使用重定向时,注意重定向符号(>、>>、<)与文件描述符或文件名之间的空格。通常,重定向符号与文件描述符之间不应有空格,但与文件名之间可以有(尽管在某些情况下,为了清晰起见,也可能不加空格)。
  • 当重定向到/dev/null时,表示丢弃输出。/dev/null是一个特殊的设备文件,向它写入的数据会被系统丢弃,读取它则立即返回文件结束(EOF)。
  • 重定向是shell的功能,而不是程序本身的功能。程序只是与文件描述符打交道,shell负责将文件描述符与文件或设备关联起来。

5 环境变量

5.1 环境变量概念

  Linux系统中会用很多环境变量来记录 配置信息

  环境变量类似于全局变量,可以被各个进程访问到。我们可以通过修改环境变量来方便地修改系统配置。

5.2 查看环境变量

  列出当前环境下的所有环境变量:

env  # 显示当前用户的变量。
set  # 显示当前shell的变量,包括当前用户的变量。
export  # 显示当前导出成用户变量的shell变量。

  要查看特定环境变量的值,可以使用echo命令,例如:

echo $PATH  # 输出PATH环境变量的值

5.3 修改环境变量

(修改环境变量需谨慎,如果错误地修改了环境变量可能导致实验无法进行。如有涉及到修改环境变量的操作,请严格按照实验指导书;如果出现问题,请及时联系老师或助教)。

  修改PATH环境变量:

export PATH=$PATH:/test
echo $PATH  # 执行完后会发现,输出最后多出来了:/test

  在当前 shell 环境下修改的环境变量只在当前环境中有效。

  为了将对环境变量的修改应用到未来所有环境下,可以将修改命令放到 ~/.bashrc 文件中,建议直接把修改语句写在文件最后,因为每次执行 bash 都是从上往下执行,后执行的可以覆盖先执行的。

  修改完 ~/.bashrc 文件后,记得执行 source ~/.bashrc ,来将修改应用到当前的 bash 环境下。

  为何将修改命令放到 ~/.bashrc ,就可以确保修改会影响未来所有的环境呢?

  • 每次启动 bash ,都会先执行 ~/.bashrc
  • 每次 ssh 登陆远程服务器,都会启动一个 bash 命令行给我们。
  • 每次 tmux 新开一个 pane ,都会启动一个 bash 命令行给我们。
  • 所以未来所有新开的环境都会加载我们修改的内容。

5.4 常见环境变量

  1. HOME :用户的家目录。
  2. PATH :可执行文件(命令)的存储路径。路径与路径之间用:分隔。当某个可执行文件同时出现在多个路径中时,会选择从左到右数第一个路径中的执行。下列所有存储路径的环境变量,均采用从左到右的优先顺序。
    • 当执行一个命令时,操作系统会在 PATH 的存储路径里从左到右依次找,直到找到第一个匹配的可执行文件。因此新加入命令时,最好把路径写在原 PATH 的前面,保证命令能够被执行
    • 当一个库出现在多个环境变量的路径中时,系统只会找到最左路径里的库文件。如果只修改了靠后路径中该库的代码,程序执行时依然会执行修改前的版本而不会执行修改后的版本。因此在更新库文件的代码时一定要更新最左路径里的库文件(最好全部更新)
  3. LD_LIBRARY_PATH :用于指定动态链接库(.so文件)的路径,其内容是以冒号分隔的路径列表(除了这里的目录,操作系统也会去一些默认的专门放.so文件的目录找动态链接库)。
    • 静态库VS动态库
    • C或C++程序使用的库函数来自静态链接库或动态链接库。
      • 静态链接库的函数代码在编译时会被载入目标程序中,程序运行时不需要再次访问静态库;会导致可执行文件体积增大,且修改静态库函数后,涉及的程序需要重新编译
      • 动态链接库的函数代码不会载入目标程序,目标程序在编译链接后只会保留库函数的接口。当程序执行到使用库函数时,程序会根据操作系统 LD_LIBRARY_PATH 里的路径找到相应动态库里的函数并执行。程序执行时需要访问动态库;可执行文件体积不受函数影响,且修改动态库后涉及的程序不需要重新编译
  4. C_INCLUDE_PATH :C语言的头文件路径,内容是以冒号分隔的路径列表。
  5. CPLUS_INCLUDE_PATH :CPP的头文件路径,内容是以冒号分隔的路径列表。
  6. PYTHONPATH :Python导入包的路径,内容是以冒号分隔的路径列表。
  7. JAVA_HOME :jdk的安装目录。
  8. CLASSPATH :存放Java导入类的路径,内容是以冒号分隔的路径列表。