Linux命令行与shell编程

个人向的知识备忘录

Posted by John Young on June 20, 2025

前言

最近因为需要两地跑,工作环境于是变成了两套:windows & Mac。其中我对mac系统其实非常陌生,于是决定积极探索mac系统下的工作流。unity在mac下除了ide与我之前使用的visual studio不同,使用的是rider,其他的其实体验上差不太多。 但是我对于unix命令行以及shell编程涉及的不多,因此读了一下《Linux命令行与shell脚本编程大全》这部书,这里记录一下我个人需要备忘的东西。

1. 常用shell指令

  • man:manual, 用于查看指令的详细用法,相当于shell的内置文档
  • ls:list,列出工作目录下的文件。-F区分文件与目录;-a显示所有文件(包括隐藏文件);-R会遍历子目录;-l显示长列表,文件详细信息;ls + 参数即可过滤,支持正则表达式,例如:
    • ls f*ll
    • ls f[a-z]ll
  • pwd:present working directory,当前工作目录。
  • touch:创建空文件,或者更新文件时间戳
  • cp:copy, 复制文件。 -i进行文件覆盖前的询问;-R递归拷贝目录;cp也可以使用正则通配符
  • ln:link,软链接或硬链接一个文件。-s创建软链接,软连接类似于windows的快捷方式,是一个独立的文件,有自己的inode编号,硬链接本质上与原文件是同一个文件,二者的inode编号是一致的。硬链接只能在同一磁盘,且不能是目录,只能是文件。
  • mv:move,移动或者重命名文件/目录。
  • rm:remove,删除文件。-i给予询问;-f强制删除无询问;-r递归删除子文件,再删除目录本身。
  • rmdir:删除空文件夹
  • mkdir:创建空文件夹。-p选项可以创建深层目录,例如:
    • mkdir -p Dir1/Dir2/Dir3
  • file:查看文件类型
  • cat:查看文本文件所有内容。-n添加行号。
  • more/less:通过分页工具查看文本文件内容
  • tail:查看文本文件末尾,默认10行;-n指定显示行数;-f可以一直刷新,在显示日志输出的时候很好用
  • head:和tail类似,但查看的是文件前n行的内容

2. 更多shell指令

  • ps:progress,查看进程情况。-e显示所有进程;-f显示更多信息
  • top:相较于ps指令只能显示某一时刻的进程情况,top会运行实时程序监测进程。-o可以根据一个主键进行排序,也可以在运行时按o健重新指定主键。常见用法:
    • top -o mem: 根据内存使用情况排序
    • top -o cpu: 根据cpu使用情况排序
  • kill/pkill:kill根据pid给程序发送终止信号,-s支持发送其他信号;pkill则是以程序名代替pid的kill。
  • mount/umount:用于挂载/卸载储存设备(u盘等)
  • df:display free space,显示磁盘的使用情况
  • du:disk usage,显示某个目录下所有文件、目录的磁盘占用情况。-h以人类可读方式;-d指定深度(只显示多少层子目录)。例如如下指令可以显示当前目录占用空间最大的10个文件夹:
    • du . | sort -nr | head -10
  • sort:文本排序功能。默认是以字符串进行升序排序。-n视为数字进行排序;-r进行逆序排列;对于按字段分割的文本,-t指定文件分割符后,可以用-k指定排序字段。例如:
    • sort -t ':' -k 3 -n /etc/passwd:按照用户id对/ect/passwd进行排序
  • grep:global regular expression,使用正则表达式进行数据搜索。-n显示匹配行号;-v进行反向搜索;-e指定多个匹配模式;-c输出匹配的数量而非内容。
    • grep '^_s' /etc/passwd -c:输出/etc/passwd中所有以’_s’为开头的行的数量
  • zip:数据压缩。-r递归包含目录的子文件,否则只会添加目录到压缩文件;-m完成后删除原文件;-e添加压缩密码,可以用-p在命令里指定;-q不显示压缩状态
  • unzip:解压缩;-d指定解压目录(否则是pwd)

3. 其他unix知识点

  • shell中可以运行子shell,形成嵌套关系。创建子shell代价不小,可以用来做协程之类的功能。
  • 全局环境变量对设置它的shell及其所有子shell都是可见的;局部环境变量只对设置它的shell可见。
    • 设置局部环境变量:$ var=XXX或者$ var="hello, world", 注意等于之后不能加空格
    • 使用局部环境变量:例如$ echo $var
    • 导出为全局变量:$ export var
    • 删除环境变量:$ unset var
  • 子进程对环境变量的修改无法影响父进程,子进程的环境变量也是自己使用的一份副本
  • shell会自带一些默认环境变量,一般使用大写(因此自定义变量用小写来区分)。例如PATH表示shell的程序和命令的搜索目录,RANDOM用来返回一个随机数,HOME表示用户目录,PWD表示当前工作路径。
  • 环境变量的持久化:登陆会话时,会运行/etc/profile脚本读取/etc/.bashrc文件(如果有的话),这里可以设置环境变量。我们最好不要修改/etc/profile,而是在$HOME/.zshrc来export我们要设置的全局变量(也可以把我们的alias命令别名在这里设置)
  • 文件权限:我们ls -l时,文件信息的第一项类似于drwxr-xr--这样的字段。第一个字符表示文件类型,目录为d,链接为l,文件为-,以及其他。之后9个字符,每3个表示一种权限,分别为用户、组成员、其他成员的权限。r是read,w是write,x是execute。例如上述例子中,用户权限为rwx,可读可写可执行,而其他用户只读。
  • 文件所有者,或者root用户,可以使用chmod命令修改文件权限。有两种方法,8进制模式和符号模式。例如:
    • chmod 664 file_name是8进制模式,会为文件赋予rw-rw-r–的权限,其中6的二进制为110,4的二进制为100,以比特位记录r, w, x三者的状态。
    • chmod o+r file_name是符号模式,它为其他用户(others)添加了读取权限(r)。再比如chmod u-x file_name为用户(user)删除了执行权限(x)。u、g、o分别表示用户、组、其他人,a表示上述三者之和。

4. vim编辑器

vim编辑器是一种强大且流行的文本编辑器。如果想使用无鼠标的工作流(一直在我的兴趣范围内),那学点vim会有很多好处。unix系统的vim基本都是预装的,不需额外步骤就能快速上手。vim不是ide,但是大部分主流ide都有vim插件。

vim的学习本身就是一个单独的课题,这里我只列一些我作为初学者学到的基础知识。

4.1 vim的键位图:

4.2 vim最基础操作

stackoverflow上有一个经典问题:“怎么退出vim?”,我们至少要知道这个问题的答案哈哈。如果再加上基础的增删改操作,那就是vim基础使用方法了。

首先是vim有三种工作模式,插入模式、命令模式以及命令行模式。刚开始我们处于命令模式。

我们输入文字其实是在插入模式下进行的,这个模式在命令模式中按i键进入,按ecs键退出。

在命令模式下,我们可以按:键进入命令行模式,同样是按ecs退出命令行模式。在命令行模式下我们可以进行文件保存等操作。例如:wq(write & quit)可以保存并退出vim。

理解了vim的三种模式其实我们就可以进行最原始的编辑文本操作了。

4.3 vim的按键的一些英文含义

vim的命令是有些许基于英语的语义的,了解这一点可以方便我们记忆。 例如:

  • 动词:
    • d -> delete,删除
    • r -> replace, 替换
    • c -> change,修改
    • y -> yank,复制
    • v -> visual,可视化选取
    • u -> undo,撤销
    • o -> open below/above,在上面/下面另起一行
    • f/F -> find char/”back” find char,查找/反向查找字符
    • a -> append,附加
    • p/P -> paste, 在光标下方/上方粘贴
    • j -> join,合并两行
    • x -> cross,删除
    • n -> next,下一个搜索结果(N为上一个)
  • 名词:
    • w -> word,单词
    • s -> sentence
    • p -> paragraph
    • t -> tag
  • 介词
    • i -> inside,在…之内
    • a -> around, 环绕
    • t -> till,到…之前
    • f -> forward,到…位置上
  • 特殊
    • hjkl,历史原因,功能和键盘方向键相同
    • 数字是组合命令,命令前加数字表示重复多少次,例如4p,粘贴4次
    • z是组合命令,zt把当前光标位置置于屏幕顶部(top),zb把光标位置置于底部(bottom),zz置于中间;
    • 大写的Z也是组合命令,ZZ是保存退出,ZQ是不保存退出
    • g是组合命令,gg是文首,gf打开光标处文件名
    • Ctrl + r,redo
    • /和?分别是向下搜索和向上搜索

一些命令的组合在语义上是说得通的,例如:

  • d3w:delete 3 words, 删除三个单词
  • ciw:change inside word, 修改一个单词

4.4 常用的vim操作

  • 导航
    • h j k l:方向键,前面加上数字可以重复n次
    • 0/HOME:跳到行首
    • $/END:跳到行尾
    • G:跳到最后一行
    • nG:跳到第n行
    • gg:跳到第一行,相当于1G
    • w:跳到下一个单词首
    • b:跳到上一个单词首,如果在中间,则跳到本单词首
    • e:跳到下一个单词末,如果在中间,则跳到本单词末
    • (/):跳到上/下一行
    • {/}:跳到上/下一段
  • 复制、删除
    • dd:剪切一行
    • yy:复制一行
    • p:粘贴
    • x:删除一个字符
    • J:将光标所在行与下一行的数据结合成同一行
    • y$/d$:复制/删除光标(包括)到行末间的字符
    • y0/d0:复制/删除光标(不包括)到行首间的字符
    • ci(/ci[/ci{:改变括号/方括号/花括号内的内容
    • da(/da[/da{:删除括号/方括号/花括号内的内容(包括括号们本身)
    • C = c$:改变当前光标直到eol的内容
    • D = d$:删除当前光标直到eol的内容
  • 搜索、替换
    • /word:向后搜索,配合n/N进行下一个/上一个查看
    • ?word:向前搜索,配合n/N进行下一个/上一个查看
    • :n1,n2s/word1/word2/g:从n1行到n2行寻找 word1 字符串,并将该字符串取代为 word2
    • :1,$s/word1/word2/g:从第一行到最后一行寻找 word1 字符串,并将该字符串取代为 word2
  • 其他
    • :set nu:显示行号

5. Shell编程

5.1 shell基础知识

  • 创建shell脚本:普通文本文件+执行权限。chmod u+x someShellScript
  • 显示shell消息:echo命令
  • 命令替换:有两种方法可以将命令的输出赋值给shell变量.
    • var=`date`
    • var=$(date)
  • 输出重定向:
    • >: 输出到文件
    • >>: 追加到文件
  • 输入重定向:
    • <: 重定向文件到输入
    • <<: 内联输入重定向,不使用文件,使用命令行。使用两个相同的字符串标记数据起止,例如EOF
  • 管道符: , 将一个命令的输出作为下一个命令的输入
  • 数学运算:
    • 整数计算可以使用方括号,例如:var1=$[1 + 5 * 2]
    • 浮点计算可以使用bc命令。(命令替换 + 输入重定向)
  • 退出脚本:exit命令 + 退出码