目录结构

各种 Linux 系统有着大致统一的标准目录结构:(FHS)

  • / 根目录
  • 可执行文件目录
    • /bin/sbin 存放系统层面所必需的可执行文件,例如cpls等,其中/sbin存放的是需要root权限的部分
    • /usr/bin/usr/sbin 存放用户层面的可执行文件,例如gitwget
  • 库目录
    • /lib 存放系统层面所必需的的动态库,理论上是为/bin/sbin准备的,此外/lib/modules还存放内核模块
    • /usr/lib 存放用户层面的动态库,理论上是为/usr/bin/usr/sbin准备的
    • 除了lib,可能还有lib32lib64,作用类似
  • /usr/local (重要)存放管理员安装的程序,与使用apt等命令直接安装的不同,这里通常是手动编译安装的软件,这个目录很重要,下面单独讨论
  • 用户家目录(重要)
    • /root root 用户的家目录
    • /home 一般用户的家目录的父目录
      • /home/abc 名为 abc 的用户的家目录
  • /opt (重要)一般用于安装第三方提供的,可选的大型应用程序
  • /etc (重要)存放系统的配置文件和脚本,例如/etc/opt对应/opt中的应用程序的配置
  • /var 存放系统层面不断变化的文件
    • /var/log 存放系统日志文件
    • /var/cache 存放应用程序的缓存数据,应用程序需要保证在缓存丢失时不会损失数据
  • /tmp 存放临时文件,在系统重启时会被清除,并且某些情况下可能被限制大小
  • /mut 临时手动挂载外部文件系统
  • /media 自动挂载可移动媒介

下面是一些对系统重要的特殊位置,不能修改否则系统容易崩溃

  • /boot 系统启动引导
  • /dev 对应设备文件
  • /proc 提供系统进程和内核状态信息
  • /sys 提供系统设备、驱动和一些内核特性的信息。
  • /run 提供系统运行时数据,例如进程ID等(通常在系统启动时创建,在重启后清除)

文件系统会大致生成一个树结构,抽象文件系统与物理磁盘空间存在对应关系,与磁盘的挂载位置有关,lsblk命令可以查询磁盘挂载情况

  • 根目录总是要挂载一个物理磁盘
  • 可以给某个目录挂载一个磁盘,例如/a,此时/a的下级的文件树都会对应到这个挂载磁盘上
  • 任一目录实际的物理位置,是沿着树结构不断往上寻找,最近的挂载磁盘,如果一直没有就找到根目录的磁盘

文件列表和权限

在任何目录下使用ll -a会列表展示目录下的所有信息,每一行开头的缩写码是文件或目录的权限,例如

1
2
drwxrwxr-x 2 abc abc 4096 Sep 30 00:25 test
-rw-r--r-- 1 abc abc 4096 Sep 30 02:25 hello.py
  • 第一部分的字符串代表文件类型和权限
    • 第一位代表文件类型
      • d 目录
      • - 普通文件
      • l 链接(快捷方式)
      • c 字符设备比如鼠标键盘
      • b 块设备比如磁盘
    • 后九位分成三组表明三类用户所拥有的rwx权限(对应位置为横线,则表示没有这个权限)
      • 123 位 文件拥有者(一般是创建者)拥有的权限
      • 456 位 文件所在组的用户拥有的权限
      • 789 位 其他用户拥有的权限
  • 第二部分对于目录而言,就是目录下的文件数,对于普通文件而言,就是链接数
  • 第三部分表示文件的拥有者
  • 第四部分表示文件所在组
  • 第五部分表示文档容量大小,单位字节,可以改成ll -h,这样显示的容量大小单位会更加直观
  • 第六部分表示文档最后修改时间,注意不是文档的创建时间
  • 第七部分表示文档名称,以点.开头的是特殊目录(.代表当前目录,..代表上一级目录)和隐藏文件

rwx 权限的具体含义为:

  • r 读权限 对一般文件含义是可以读取文件内容;对目录含义是可以ls打印目录
  • w 写权限 对一般文件含义是可以修改文件内容,但是不能删除该文件(删除需要对该文件所在目录拥有写权限);对目录含义是可以在目录下创建+删除+重命名文件
  • x 执行权限 对一般文件含义是当作程序执行;对目录含义是可以进入这个目录

我们也可以通过ls给出的文件/目录的颜色去区分类型和权限:

  • 白色代表普通文件
  • 蓝色代表目录
  • 绿色代表可执行文件/脚本(赋予当前用户执行权限时,颜色就会从白色变成绿色)
  • ...

shell 脚本

在 shell 中执行一个 shell 脚本时,相当于开了一个 shell 子进程,脱离了当前的环境,因此

  • shell 脚本中的修改通常只能继承父进程的部分内容,比如父进程中定义的变量,在子进程中仍然未定义。
  • 子进程的修改通常不会反过来影响父进程中的 shell,比如在脚本中定义了变量,退出脚本后这种定义通常是无效的。

这种设置是为了安全考虑,隔离了父进程和子进程之间的相互影响,但是有时候我们需要继承或者反馈信息:

  • 对于第一种继承问题,我们需要指定这个变量是具有导出属性的,使用 export 命令,此时变量会被子 shell 继承
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 定义变量的同时增加导出属性
export a b=3
# 当然也可以先定义后增加导出属性
b=3
export b

# 删除变量的导出属性
export -n a b

# 为已定义函数增加导出属性
export -f func_1 func_2

# 删除函数的导出属性
export -fn a b
  • 对于第二种反馈问题,如果我们希望 shell 脚本 a.sh 在调用另一个 shell 脚本 b.sh 时,影响可以反馈给自己,可以在 a.sh 中使用 source 语句
1
2
source b.sh
. b.sh # 等价写法 小数点后接空格

家目录结构

常见配置文件

在家目录下常见的用户级配置文件如下,在ls命令下会隐藏这些.开头的文件,可以通过ll -a查看,例如

  • 与各种 shell 相关
    • .bash_profile 重要的一个配置文件,它在用户每次登录系统时被读取,里面的所有 命令都会被 bash 执行。
    • .bashrc 重要的一个配置文件,会在 bash shell 调用另一个 bash shell 时读取,也就是在 shell 中再键入 bash 命令启动一个新 shell 时就会去读该文件。这样可有效分离登录和子 shell 所需的环境。一般来说都会在.bash_profile里调用.bashrc脚本以便统一配置用户环境。
    • .bash_logout
    • .bash_history.sh_history bash 的命令历史记录
    • .kshrc.mkshrc.zshrc 别的 shell
  • 与 vim 相关的
    • .vimrc vim 的用户级配置文件
    • .viminfo vim 的命令历史记录
  • 与 Xshell 相关的
    • .Xauthority

/etc目录的也有.bashrcprofile等配置文件,这是系统级(全局)的配置文件,优先级比用户级配置更低,当在用户主目录下找不到.bash_profile.bashrc时,就会读取这两个文件。(其它应用的配置文件也类似,比如 vim 和 git 也存在系统级和用户级的配置文件,都存放在相应的位置)

XDG 规范

历史原因导致了家目录下的各种配置文件和文件夹非常混乱,FreeDesktop.org 推出了XDG 基础目录规范(XDG Base Directory Specification), 用于在 Linux 系统中标准化用户数据、配置文件、缓存和其他运行时文件的存放位置。

该规范定义了一些环境变量,用于指示软件应该将这些文件存储在何处,而不是将它们混乱存放在用户的家目录中。目前只有部分软件严格遵循了这个规范,还有部分软件在保持自身历史习惯的同时也兼容 XDG 规范。

XDG 基础目录规范主要包括以下几个环境变量所定义的目录:

  • ~/.config(可以通过XDG_CONFIG_HOME修改):存放用户级的配置文件,例如fish将配置文件存放在~/.config/fish/目录下
  • ~/.local/:用户的程序目录,大致替代/usr/local,因为/usr/local/需要管理员权限,普通用户无权限时可以安装到此处
    • ~/.local/bin:存放用户的可执行文件
    • ~/.local/lib~/.local/include:存放用户的库文件以及对应的头文件
    • ~/.local/share(可以通过XDG_DATA_HOME修改):存放用户的应用程序数据文件,例如桌面文件、图标、插件、字体、游戏存档等
  • ~/.cache(可以通过XDG_CACHE_HOME修改):存储用户的缓存文件,例如临时生成的文件、缩略图等

例如

1
2
3
4
5
6
7
$HOME
├── .config/ # 用户级的配置文件(XDG_CONFIG_HOME)
├── .local/
│ ├── share/ # 应用程序数据(XDG_DATA_HOME)
│ ├── bin/ # 用户的可执行文件
│ └── lib/ # 用户的库文件
└── .cache/ # 缓存文件(XDG_CACHE_HOME)

环境变量

环境变量就是系统层面需要给应用层面提供的一个"词典",每一项由变量名和变量值(字符串)组成,通常包括应用所需要的路径,系统信息等。 不同的 shell,不同的进程,不同的状态下的环境变量可能是不一样的。

通常由一些配置脚本生成相应的环境变量,这些脚本在 shell 启动时会自动执行一遍;也可以手动修改环境变量,不过这种修改通常是临时性的,退出 shell 后就会失效,想要永久性地设置环境变量,需要修改相应的配置脚本。

env命令可以查看当前状态下的所有环境变量,例如

1
2
3
4
5
6
7
...
HOME=/home/username
PERL_LOCAL_LIB_ROOT=:/home/username/perl5
LOGNAME=username
QTLIB=/usr/lib64/qt-3.3/lib
CVS_RSH=ssh
...

可以输出指定的环境变量,其实环境变量也是 shell 脚本中一种特殊的变量,因此使用美元符号作为前缀访问,注意 shell 变量是大小写敏感的,并且通常环境变量采用全大写的形式

1
2
3
4
5
echo $HOME # 这个环境变量让应用可以找到家目录
/home/username

echo $PATH
/opt/cmake-3.14.1-Linux-x86_64/bin:/opt/intel//impi/5.0.2.044/intel64/bin...

其中的 PATH 是非常重要的环境变量,包括一些存放可执行文件,链接库等等的目录(路径之间通过冒号:分隔),许多应用都需要在 PATH 里面添加指定的路径才能正常执行,我们需要修改这个环境变量,或者创建一些新的环境变量。常见的做法是,在 PATH 中添加新的路径,如下在 PATH 的最后加了一个路径,也可以加在最前面,但是注意路径的顺序就是检索的顺序,因此不同的顺序会导致不同的优先级,可能产生 bug。

1
PATH=$PATH:$HOME/bin
  • 如果希望临时性的修改环境变量,那么可以直接在 shell 中输入语句,例如PATH=$PATH:$HOME/bin,但是如果重新开一个 shell,比如执行一个 shell 脚本,或者退出重新登录,环境变量就会恢复原装
  • 如果希望永久性修改环境变量,就需要在用户家目录下的.bashrc配置文件中使用语句,例如
1
2
3
export PATH=$PATH:$HOME/bin # 可以使用export命令

declare -x HISTSIZE="1000" # 也可以使用declare -x命令,设置环境变量,具有同样的效果

软件安装

大致介绍一下在Linux系统中安装软件的几种方式。

通过包管理器安装

系统自带的包管理器可以用于安装软件,这是最简单的一种方法,只需要一条命令即可,例如

1
sudo apt-get install nginx

但是这种方法有两个显著的局限性:

  • 考虑到稳定性,这种方式获取的软件版本可能不是最新的;
  • 安装命令需要root权限,普通用户无法安装。

举个例子,通过apt安装nginx,安装过程大致可能为:

  • 把可执行文件存放到 /usr/sbin/nginx
  • 把库文件存放到 /usr/lib/nginx/modules/
  • 把配置文件存放到 /etc/nginx/,例如配置文件/etc/nginx/nginx.conf
  • 把文档文件存放到 /usr/share/doc/nginx/
  • ...

通过源码编译安装

我们先关注/usr/local目录的结构,它通常包括如下内容:

  • /usr/local/bin/usr/local/sbin 存放可执行文件,通常是由源代码构建安装得到的
  • /usr/local/lib 存放程序的共享库文件,通常是为 /usr/local/bin/usr/local/sbin 中的可执行程序准备
  • /usr/local/include 存放 C 和 C++ 头文件
  • /usr/local/share 存放共享数据(如文档、图标、字体、locale 数据、示例配置等)
  • /usr/local/man 存放软件的手册页文件。这些文件可以通过 man 命令进行访问,帮助用户查看自定义安装软件的说明文档
  • /usr/local/etc 存放软件的配置文件。与系统的 /etc 类似,但用于存放本地安装的程序的配置
  • /usr/local/src 存放软件的源代码文件
  • /usr/local/tmp 用于存放本地程序运行时生成的临时文件

值得注意的是,usr不是user的缩写,是unix system resources的缩写。

管理员在手动通过源码编译安装一个软件时,在编译完成之后,需要将软件的对应部分正确存放在对应位置,这个行为通常会在安装脚本中提供,这里举一个例子,例如我们编译了一个名为demo的C++程序,安装过程大致包括:

  • 把可执行文件存放到 /usr/local/bin(这样可以直接运行,不需要修改PATH环境变量)
  • 把库文件存放到 /usr/local/lib,对应的头文件存放在/usr/local/include(如果在其它位置,我们还需要手动处理环境变量,否则找不到库文件)
  • 把全局配置文件存放到 /usr/local/etc
  • 把文档文件存放到 /usr/local/share/doc/demo
  • 把手册页文件存放到 /usr/local/share/man(这样才能支持man命令)

除此之外,程序在运行时:

  • 如果需要生成临时文件,可以将其放置在/tmp
  • 如果需要生成日志,可以把日志文件放置在/var/log/demo

安装到/opt目录

前面列举的两种方式有一个共性:将程序的各个部分直接“嵌入”到系统的各个目录中,各个软件之间并没有进行隔离。 但是这种方式对于某些程序的安装是不合适的,尤其是那些与发行版无关的大型第三方软件(例如MATLAB),此时我们需要的是第三种安装方式:直接安装到/opt目录。

如果软件官方提供的是二进制安装包(如 .tar.gz.zip 等),通常建议将安装包直接解压到/opt的对应目录中,例如 /opt/google/chrome。 在其它情况下,遵循教程或安装脚本的提示即可,但是行为也是大致类似的。

由于我们将软件的主要文件都存放/opt/<name>目录下,这使得它与系统中的其它软件保持相对的隔离,也和系统的包管理器无关,这便于专门管理和卸载,例如在卸载时通常只需要删除/opt/<name>目录

这类软件通常都是自包含的,即自身运行需要的所有二进制文件、库文件、文档、配置文件都会主要存放在自己的根目录下,通常会在自己的根目录下维护一套类似的目录,例如

  • 主可执行文件通常存放在 /opt/<name>/bin//opt/<name>/ 根目录下
  • 专用库文件通常存放在 /opt/<name>/lib/
  • 配置文件可能存放在 /opt/<name>/etc/
  • 文档文件会存放在 /opt/<name>/doc//opt/<name>/share/doc/

系统监控

df 命令

以可读形式展示文件系统的硬盘空间使用情况

1
df -h

输出内容形如

1
2
3
4
5
6
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs 32G 0 32G 0% /dev
/dev/sda3 560G 194G 338G 37% /
/dev/sda1 477M 291M 157M 65% /boot
/dev/sdb1 16T 12T 3.0T 80% /home
...

这里根目录/对应560G空间,已经使用了 37% 的空间, 用户目录/home对应16T空间,已经使用了 80% 的空间。

dh 命令

以可读形式展示test/目录下所有子项在磁盘中的大小

1
du -h test/

如果显示子项太多,可用使用-s选项则会进行汇总

1
du -sh test/

可以对输出结果按照大小进行排序

1
du -sh test/ | sort -hr

top 命令

top命令可用动态查看当前 CPU 占用情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
top - 21:05:47 up 12 days, 13:50,  2 users,  load average: 1.04, 1.21, 1.66
Tasks: 334 total, 1 running, 333 sleeping, 0 stopped, 0 zombie
%Cpu(s): 3.6 us, 0.1 sy, 0.0 ni, 96.4 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 26385062+total, 25013684+free, 10826344 used, 2887432 buff/cache
KiB Swap: 32767996 total, 32767996 free, 0 used. 25193814+avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
28967 xxxxxx 20 0 19.467g 8.531g 152140 S 102.0 3.4 151:43.66 MATLAB
31585 xxxxxx 20 0 166192 2876 1944 R 0.3 0.0 0:00.08 top
1 root 20 0 49184 5560 2440 S 0.0 0.0 0:33.60 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.13 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:00.25 ksoftirqd/0
8 root rt 0 0 0 0 S 0.0 0.0 0:00.60 migration/0
9 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcu_bh
10 root 20 0 0 0 0 S 0.0 0.0 2:23.79 rcu_sched
11 root rt 0 0 0 0 S 0.0 0.0 0:03.06 watchdog/0

对于头部信息的解读:

  • 第一行:系统时间,系统运行时间,当前登录的用户数量,系统负载平均值(低于1代表空闲,高于1代表繁忙)
  • 第二行:当前总进程数,正在执行的进程数
  • 第三行:进程占用的 CPU 百分比
    • 3.6 us代表用户空间进程占用,包括大部分应用程序;
    • 0.1 sy代表内核空间进程占用,用于执行系统内核和驱动程序等;
    • 96.4 id代表CPU空闲时间占比。
  • 第四行:系统总内存量,空间的内存量,已使用的内存量

对于进程列表的解读:

  • PID:进程ID。
  • USER:进程所有者的用户名。
  • PR:进程优先级。
  • NI:进程的 nice 值(优先级调整值)。
  • VIRT:进程使用的虚拟内存总量。
  • RES:进程使用的常驻内存量。
  • SHR:进程使用的共享内存量。
  • S:进程状态(例如:R 运行、S 睡眠、D 不可中断睡眠、Z 僵尸、T 停止)。
  • %CPU:进程消耗的 CPU 百分比。(可能超过百分之一百,这是并行的原因)
  • %MEM:进程使用的内存百分比。
  • TIME+:进程使用的总 CPU 时间,单位为秒。
  • COMMAND:执行进程的命令名称或命令行。

常用命令

目录相关

cdls是最常用的两个命令。

cd命令用于改变目录:

  • cd <path>:切换到<path>目录下,可以是相对路径或/开头的绝对路径;
  • cd:缺省<path>则会回到家目录~
  • cd .. 返回上一级目录
  • cd -可以回到上一次所处的位置

ls命令用于列出目录下的文件:

  • ls <path>:列出目录下的所有文件
  • ls:缺省<path>则会列出当前目录下的文件
  • ls -a:除了普通文件,还显示以.开头的隐藏文件(文件夹),可以用ls -a | grep '^\.'过滤,只显示隐藏文件(文件夹)
  • ll:通常等价于ls命令加上列表显示选项ls -l(取决于.bashrc中定义的别名)
  • ll -a:通常等价于ls命令加上列表显式选项和显示全部选项ls -al,列表显示选项会显示以.开头的隐藏文件(文件夹)

mkdir命令用于创建空目录:

  • mkdir <demo>:新建空目录<demo>
  • mkdir -p a/b/c:创建多级目录,如果中间目录不存在则自动创建

touch命令可以创建一个空文件,如果同名文件已经存在,touch不会修改它的实际内容,但是会更新一下它的创建时间等信息。

在服务器上直接编辑文件需要使用vim,过于复杂不做讨论,我们可以用远程文件传输替代在服务器上直接修改文件,误打开vim时使用:q!可以强制退出vim并且不做任何修改。

rmrmdir命令用于删除文件/空目录:

  • rm <demo>:删除文件或目录 <demo>
  • rm -f <demo>:强制删除文件或目录 <demo>
  • rm -i <demo>:询问互动式删除 <demo>,需要确认一遍文件名
  • rm -r <path>:递归删除路径<path>,常用于删除非空目录和里面的全部内容
  • rmdir <demo>:删除空目录<demo>,注意只能删空目录

cpmv是拷贝和移动命令:

  • cp <demo> <path>:把文件或目录 <demo> 拷贝到 <path> 目录
  • cp <demo1> <demo2>:把文件或目录 <demo1> 拷贝为 <demo2>
  • cp <demo> <path>/<demo2>:上面两种操作的组合:拷贝+重命名
  • mv <demo> <path>:把文件或目录 <demo> 移动到 <path> 目录
  • mv <demo1> <demo2>:把文件或目录 <demo1> 重命名为 <demo2>
  • mv <demo> <path>/<demo2>:上面两种操作的组合:移动+重命名

查询信息

  • clear:清屏(ctrl+l也可以)
  • whowhoami:显示当前用户名,两者的判定规则略有区别,尤其是涉及用户切换时
  • pwd:显示当前目录
  • echo:输出内容到控制台,例如echo 'hello'输出字符串,echo $PATH输出PATH环境变量
  • cal 显示日历表
  • date 输出日期时间,例如Mon Oct 3 21:59:14 CST 2022
  • history 10 查看最近执行的 10 条历史命令 !3可以再次执行 history 中编号为 3 的命令

查看文件

  • cat <file> 查看<file>的全部内容,cat -n <file>会显示行号。通常cat会搭配管道符使用,例如使用cat <file> | more搭配more命令查看大文件
  • head <file> 查看<file>的开头几行(默认显示10行内容,可以加参数修改行数,例如-n 20,下同)
  • tail <file> 查看<file>的末尾几行
  • tail -f <file> 动态更新地查看<file>文件的末尾几行,适合监控动态增长的日志文件,例如tail -f /var/log/syslog
  • more <file> 一页一页地查看 <file>
  • less <file> 一页一页地查看 <file>,而且使用比 more 更便利,支持向前翻页;加载大文件时会部分读取,因此不会很卡。

有时候一个文件太大了,我们只需要截取中间的一部分来输出(如果是头部或尾部,直接使用headtail即可),使用cat全部输出不太方便,在vim中复制又不方便,可以参考下面的做法:

  1. 使用vim查看文件,开启行号显示:set number
  2. 确定需要输出的片段的起止行
  3. 执行shell命令:!awk -n "5,10p" filename

如果已经确定了片段的起止行,也可以直接在shell中使用awk -n "5,10p" filename

对于tail -f <file>,在Windows上的powershell有相似的命令,可以用于监控动态增长的日志

1
Get-Content -Path <file> -Wait

查找文件

find命令用于查找文件,下面提供几个例子:

  • 查找/home目录下(包括子目录下)的名称为 a.txt 文件 find /home -name a.txt 也支持文件名通配符
  • 查找/opt目录下(包括子目录下)的拥有者为 username 的文件 find /opt -user username
  • 查找/home目录下(包括子目录下)的大小超过 200M 的文件 find /home +200M (+n 大于 -n 小于,n 等于;支持的单位有 k,M,G 等)

修改文件属性

修改文件权限的指令是chmod,常见用法如下

  • chomd u=rwx,g=rx,o=x filename:u 是拥有者,g 是所在组,o 是其他人,直接指定文件的各个权限
  • chmod u+x filenamechmod u-x filename:给拥有者增加/撤销该文件的执行权限
  • chmod 777 filename:使用二进制编码来简写,例如 777 代表二进制的111111111,也就是给三类人所有权限,例如 751 就是111101001

即使是普通用户自己创建的文件,也不会自动拥有它的所有权限,可以使用命令给自己拥有的文件赋予合理的权限,root 用户拥有绝对的能力,即使一个文件非它创建,它也可以修改这个文件的权限。

通常情况下,普通用户对自己的家目录有完全的权限,对/etc/tmp/opt之类的目录中的文件,只有读和执行的权利,只有对目录下属于用户自己的文件拥有写的权限。

最常见的情景是,直接创建的一个 shell 脚本是不能直接执行的(在目录中不是绿色的),使用chmod 777 filename或者类似指令赋予足够的权限,变成绿色。

1
2
3
4
# 这样总可以执行
sh ./a.sh
# 这个必须对a.sh拥有执行权限才可以
./a.sh

修改文件拥有者和文件所在组的指令是chown,常见用法如下

  • chown newowner filename:修改文件拥有者
  • chown :newgroup filename:修改文件所在组
  • chown newowner:newgroup filename:同时修改文件拥有者和文件所在组

补充:对于chmodchown命令,加上-R选项才会进行递归修改,否则对于目录只会修改目录自身,不会修改其中的子目录和子文件。

输出重定向

在Linux的shell中可以通过如下方式将输出重定向:

  • 标准输出重定向到指定文件:>采用覆盖方式,>>采用追加方式。若目标文件不存在则会自动创建,下同。例如cat a.txt > b.txtecho hello >> a.txt
  • 错误输出重定向到指定文件:2>采用覆盖方式,2>>采用追加方式。
  • 合并标准输出和错误输出重定向到指定文件:&>采用覆盖方式,&>>采用追加方式。
  • 一个特别的用法:do_something > /dev/null,将命令产生的标准输出重定向到 /dev/null,相当于将输出内容都丢弃到“垃圾桶”。

补充:对于Window上的powershell,同样也支持使用>>>将标准输出重定向,对于错误输出则需要其它的语法,丢弃标准输出可以使用do_something > $null,或者使用do_something | Out-Null

符号链接

Linux系统的符号链接(软链接)效果大致相对于Windows系统的快捷方式。

基本使用如下(必须加上-s选项)

1
ln -s /path/to/original/file /path/to/symlink

这个命令会创建符号链接/path/to/symlink,它指向的目标文件为/path/to/original/file

对于软链接的访问会直接访问到目标文件,例如使用 vim 打开。对软链接的重命名,得到的结果仍然是一个指向原本目标文件的软链接。 对软链接的删除只会删除符号链接自身,不会影响指向的文件;

注:

  • 如果不使用-s选项就会创建硬链接,硬链接的机制和软链接是不同的,它和实际文件在文件系统中的地位是等价的,都指向同一个实际内存;
  • 如果软链接失效(指向的文件不存在,可能在 shell 中显示红色警告)

用户切换

使用su user可以切换到user用户,但是注意这个切换不会加载user用户的环境变量和配置文件,更建议的用法是su - user

杀死进程

如果某个进程卡死了,可以使用ctrl+z将其挂起,然后使用下面的命令按照关键字查找进程id(关键字可以是用户名或者具体命令的单词)

1
ps -aux | grep <keyword>

然后可以杀死对应进程

1
2
3
4
kill id

# kill force
kill -9 id