8941 words
45 minutes
Linux Command Line
2025-08-27

简单命令#

查看磁盘剩余空间的数量,输入 df

显示空闲内存的数量,输入命令 free

whoami查看当前用户

一般用“把变量引起来,为了避免变量里面的空格影响解析

echo -n输出后不换行

文件/目录#

ls可以接两个文件夹

mkdir -p 递归创建

stat展示文件的详细信息

ls -lt —reverse 按照时间逆序

表 4-1: ls 命令选项

选项长选项描述
-a—all列出所有文件,甚至包括文件名以圆点开头的默认会被隐藏的隐藏文件。
-d—directory通常,如果指定了目录名,ls 命令会列出这个目录中的内容,而不是目录本身。 把这个选项与 -l 选项结合使用,可以看到所指定目录的详细信息,而不是目录中的内容。
-F—classify这个选项会在每个所列出的名字后面加上一个指示符。例如,如果名字是 目录名,则会加上一个’/‘字符。
-h—human-readable当以长格式列出时,以人们可读的格式,而不是以字节数来显示文件的大小。
-l以长格式显示结果。
-r—reverse以相反的顺序来显示结果。通常,ls 命令的输出结果按照字母升序排列。
-S命令输出结果按照文件大小来排序。
-t按照修改时间来排序。

file filename 查看file的详细信息

less 允许查看文件 g为首行,n查找,q退出

表 4-4: Linux 系统中的目录

目录评论
/boot包含 Linux 内核,最初的 RMA 磁盘映像(系统启动时,由驱动程序所需),和 启动加载程序。有趣的文件: /boot/grub/grub.conf or menu.lst, 被用来配置启动加载程序。 /boot/vmlinuz,Linux 内核。
/dev这是一个包含设备结点的特殊目录。“一切都是文件”,也使用于设备。 在这个目录里,内核维护着它支持的设备。
/etc这个目录包含所有系统层面的配置文件。它也包含一系列的 shell 脚本, 在系统启动时,这些脚本会运行每个系统服务。这个目录中的任何文件应该是可读的文本文件。有意思的文件:虽然/etc 目录中的任何文件都有趣,但这里只列出了一些我一直喜欢的文件: /etc/crontab, 定义自动运行的任务。 /etc/fstab,包含存储设备的列表,以及与他们相关的挂载点。/etc/passwd,包含用户帐号列表。
/lost+found每个使用 Linux 文件系统的格式化分区或设备,例如 ext3文件系统, 都会有这个目录。当部分恢复一个损坏的文件系统时,会用到这个目录。除非文件系统 真正的损坏了,那么这个目录会是个空目录。
/media在现在的 Linux 系统中,/media 目录会包含可移除媒体设备的挂载点, 例如 USB 驱动器,CD-ROMs 等等。这些设备连接到计算机之后,会自动地挂载到这个目录结点下。
/opt这个/opt 目录被用来安装“可选的”软件。这个主要用来存储可能 安装在系统中的商业软件产品。
/proc这个/proc 目录很特殊。从存储在硬盘上的文件的意义上说,它不是真正的文件系统。 反而,它是一个由 Linux 内核维护的虚拟文件系统。它所包含的文件是内核的窥视孔。这些文件是可读的, 它们会告诉你内核是怎样监管计算机的。
/sbin这个目录包含“系统”二进制文件。它们是完成重大系统任务的程序,通常为超级用户保留。
/tmp这个/tmp 目录,是用来存储由各种程序创建的临时文件的地方。一些配置,导致系统每次 重新启动时,都会清空这个目录。
/usr在 Linux 系统中,/usr 目录可能是最大的一个。它包含普通用户所需要的所有程序和文件。
/usr/bin/usr/bin 目录包含系统安装的可执行程序。通常,这个目录会包含许多程序。
/usr/local这个/usr/local 目录,是非系统发行版自带,却打算让系统使用的程序的安装目录。 通常,由源码编译的程序会安装在/usr/local/bin 目录下。新安装的 Linux 系统中,会存在这个目录, 但却是空目录,直到系统管理员放些东西到它里面。
/usr/sbin包含许多系统管理程序。
/usr/share/usr/share 目录包含许多由/usr/bin 目录中的程序使用的共享数据。 其中包括像默认的配置文件,图标,桌面背景,音频文件等等。
/usr/share/doc大多数安装在系统中的软件包会包含一些文档。在/usr/share/doc 目录下, 我们可以找到按照软件包分类的文档。
/var除了/tmp 和/home 目录之外,相对来说,目前我们看到的目录是静态的,这是说, 它们的内容不会改变。/var 目录是可能需要改动的文件存储的地方。各种数据库,假脱机文件, 用户邮件等等,都驻扎在这里。
/var/log这个/var/log 目录包含日志文件,各种系统活动的记录。这些文件非常重要,并且 应该时时监测它们。其中最重要的一个文件是/var/log/messages。注意,为了系统安全,在一些系统中, 你必须是超级用户才能查看这些日志文件。
通配符意义
*匹配任意多个字符(包括零个或一个)
?匹配任意一个字符(不包括零个)
[characters]匹配任意一个属于字符集中的字符
[!characters]匹配任意一个不是字符集中的字符
[[:class:]]匹配任意一个属于指定字符类中的字符
字符类意义
[:alnum:]匹配任意一个字母或数字
[:alpha:]匹配任意一个字母
[:digit:]匹配任意一个数字
[:lower:]匹配任意一个小写字母
[]匹配任意一个大写字母

cp /mv#

cp

选项意义
-a, —archive复制文件和目录,以及它们的属性,包括所有权和权限。 通常,复本具有用户所操作文件的默认属性。
-i, —interactive在重写已存在文件之前,提示用户确认。如果这个选项不指定, cp 命令会默认重写文件。
-r, —recursive递归地复制目录及目录中的内容。当复制目录时, 需要这个选项(或者-a 选项)。
-u, —update当把文件从一个目录复制到另一个目录时,仅复制 目标目录中不存在的文件,或者是文件内容新于目标目录中已经存在的文件。
-v, —verbose显示翔实的命令操作信息
cp file1 file2 dir1多个文件cp
-a, —archive复制文件和目录,以及它们的属性,包括所有权和权限。 通常,复本具有用户所操作文件的默认属性。

mv的i u v与cp相同

命令#

  1. type command 显示command 的用法

  2. man command 手册

    手册页的顺序

    章节内容
    1用户命令
    2程序接口内核系统调用
    3C 库函数程序接口
    4特殊文件,比如说设备结点和驱动程序
    5文件格式
    6游戏娱乐,如屏幕保护程序
    7其他方面
    8系统管理员命令

    有时候,我们需要查看参考手册的特定章节,从而找到我们需要的信息。 如果我们要查找一种文件格式,而同时它也是一个命令名时,这种情况尤其正确。 没有指定章节号,我们总是得到第一个匹配项,可能在第一章节。我们这样使用 man 命令, 来指定章节号:

    man section search_term
    

    例如:

    [me@linuxbox ~]$ man 5 passwd
    

    命令运行结果会显示文件 /etc/passwd 的文件格式说明手册。

  3. 可以把多个命令放在同一行上,命令之间 用”;”分开

  4. alias unalias

重定向#

将错误也重定向到同一个文件

ls -l /bin/usr &> ls-output.txt

cat输入完之后按ctrl+d

uniq删除重复行,uniq -d看到重复行

ls /bin /usr/bin | sort | uniq -d | less

wc(字计数)命令是用来显示文件所包含的行,字和字节数 wc -l只显示行数

head -n 5
tail -n 5
tail -f /var/log/messages

使用”-f”选项,tail 命令继续监测这个文件,当新的内容添加到文件后,它们会立即 出现在屏幕上。这会一直继续下去直到你输入 Ctrl-c。

tee - 从 Stdin 读取数据,并同时输出到 Stdout 和文件

... | tee output.txt | ...

括号展开#

echo Number_{1..5}
echo {Z..A}
echo a{A{1,2},B{3,4}}b
aA1b aA2b aB3b aB4b

展开变量列表

printenv | less

$()把括号内的值替换括号

如果你把文本放在双引号中, shell 使用的特殊字符,除了 $\ (反斜杠),和 `(倒引号)之外, 则失去它们的特殊含义,被当作普通字符来看待。

如果需要禁止所有的展开,我们使用单引号

[me@linuxbox ~]$ echo text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER
text /home/me/ls-output.txt a b foo 4 me
[me@linuxbox ~]$ echo "text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER"
text ~/*.txt   {a,b} foo 4 me
[me@linuxbox ~]$ echo 'text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER'
text ~/*.txt  {a,b} $(echo foo) $((2+2)) $USER

echo 命令带上 ‘-e’ 选项,能够解释转义序列

键盘操作#

表9-1: 光标移动命令

按键行动
Ctrl-a移动光标到行首。
Ctrl-e移动光标到行尾。
Ctrl-f光标前移一个字符;和右箭头作用一样。
Ctrl-b光标后移一个字符;和左箭头作用一样。
Alt-f光标前移一个字。
Alt-b光标后移一个字。
Ctrl-l清空屏幕,移动光标到左上角。clear 命令完成同样的工作。

表9-2: 文本编辑命令

按键行动
Ctrl-d删除光标位置的字符。
Ctrl-t光标位置的字符和光标前面的字符互换位置。
Alt-t光标位置的字和其前面的字互换位置。
Alt-l把从光标位置到字尾的字符转换成小写字母。
Alt-u把从光标位置到字尾的字符转换成大写字母。

表9-3: 剪切和粘贴命令

按键行动
Ctrl-k剪切从光标位置到行尾的文本。
Ctrl-u剪切从光标位置到行首的文本。
Alt-d剪切从光标位置到词尾的文本。
Alt-Backspace剪切从光标位置到词头的文本。如果光标在一个单词的开头,剪切前一个单词。
Ctrl-y把剪切环中的文本粘贴到光标位置。

用户#

setuid 位(八进制4000)。当应用到一个可执行文件时,它把有效用户 ID 从真正的用户(实际运行程序的用户)设置成程序所有者的 ID。比如我来跑root的文件,执行的用户是root

setgid 位(八进制2000),这个相似于 setuid 位,把有效用户组 ID 从真正的 用户组 ID 更改为文件所有者的组 ID。如果设置了一个目录的 setgid 位,则目录中新创建的文件 具有这个目录用户组的所有权,而不是文件创建者所属用户组的所有权。对于共享目录来说, 当一个普通用户组中的成员,需要访问共享目录中的所有文件,而不管文件所有者的主用户组时, 那么设置 setgid 位很有用处。

sudo chmod g+s /usr/local/share/Music

这会保证在目录中新建的文件用户组是目录的用户组

此外系统中默认的掩码值是0022,这会禁止用户组成员编辑属于同组成员的文件。umask 0002

chmod 命令符号表示法

u”user”的简写,意思是文件或目录的所有者。
g用户组。
o”others”的简写,意思是其他所有的人。
a”all”的简写,是”u”, “g”和“o”三者的联合。

chmod 符号表示法实例

u+x为文件所有者添加可执行权限。
u-x删除文件所有者的可执行权限。
+x为文件所有者,用户组,和其他所有人添加可执行权限。 等价于 a+x。
o-rw除了文件所有者和用户组,删除其他人的读权限和写权限。
go=rw给群组的主人和任意文件拥有者的人读写权限。如果群组的主人或全局之前已经有了执行的权限,他们将被移除。
u+x,go=rw给文件拥有者执行权限并给组和其他人读和执行的权限。多种设定可以用逗号分开。
su -c 'command'

使用这种模式,命令传递到一个新 shell 中执行。把命令用单引号引起来很重要,因为我们不想 命令在我们的 shell 中展开,但需要在新 shell 中展开。

更改文件所有者和用户组

chown [owner][:[group]] file...
passwd [user]改密码

进程#

ps aux

BSD 风格的 ps 命令列标题

标题意思
USER用户 ID. 进程的所有者。
%CPU以百分比表示的 CPU 使用率
%MEM以百分比表示的内存使用率
VSZ虚拟内存大小
RSS进程占用的物理内存的大小,以千字节为单位。
START进程运行的起始时间。若超过24小时,则用天表示。

命令之后,加上”&”字符 放到后台运行

jobs 列出从终端中启动的任务。

放到前台

fg %1 (job number)

ctrl+Z 停止,可以用bg移入后台

编号名字含义
1HUP挂起。这是美好往昔的痕迹,那时候终端机通过电话线和调制解调器连接到 远端的计算机。这个信号被用来告诉程序,控制的终端机已经“挂起”。 通过关闭一个终端会话,可以说明这个信号的作用。发送这个信号到终端机上的前台程序,程序会终止。许多守护进程也使用这个信号,来重新初始化。这意味着,当发送这个信号到一个守护进程后, 这个进程会重新启动,并且重新读取它的配置文件。Apache 网络服务器守护进程就是一个例子。
2INT中断。实现和 Ctrl-c 一样的功能,由终端发送。通常,它会终止一个程序。
9KILL杀死。这个信号很特别。鉴于进程可能会选择不同的方式,来处理发送给它的 信号,其中也包含忽略信号,这样呢,从不发送 Kill 信号到目标进程。而是内核立即终止 这个进程。当一个进程以这种方式终止的时候,它没有机会去做些“清理”工作,或者是保存劳动成果。 因为这个原因,把 KILL 信号看作杀手锏,当其它终止信号失败后,再使用它。
15TERM终止。这是 kill 命令发送的默认信号。如果程序仍然“活着”,可以接受信号,那么 这个信号终止。
18CONT继续。在停止一段时间后,进程恢复运行。
19STOP停止。这个信号导致进程停止运行,而没有终止。像 KILL 信号,它不被 发送到目标进程,因此它不能被忽略。
3QUIT退出
11SEGV段错误。如果一个程序非法使用内存,就会发送这个信号。也就是说, 程序试图写入内存,而这个内存空间是不允许此程序写入的。
20TSTP终端停止。当按下 Ctrl-z 组合键后,终端发送这个信号。不像 STOP 信号, TSTP 信号由目标进程接收,且可能被忽略。
28WINCH改变窗口大小。当改变窗口大小时,系统会发送这个信号。 一些程序,像 top 和 less 程序会响应这个信号,按照新窗口的尺寸,刷新显示的内容。

shell环境#

printenv和set可以查看环境变量

建议在 .bash_profile 里加一句让它自动加载 .bashrc

if [ -f ~/.bashrc ]; then     
    . ~/.bashrc 
fi

环境变量放在 .bash_profile,而别名、函数、shell 选项等放在 .bashrc(一般只在交互式终端中使用)。

$PS1存放了你的提示符的值

网络#

netstat -ie看接口,-r看路由表

查找文件#

locate 程序快速搜索路径名数据库,并且输出每个与给定字符串相匹配的文件名。比

find#

  1. find ~ -type d/f -name ”*.JPG” -size +1M

find 测试条件

测试条件描述
-cmin n匹配的文件和目录的内容或属性最后修改时间正好在 n 分钟之前。 指定少于 n 分钟之前,使用 -n,指定多于 n 分钟之前,使用 +n。
-cnewer file匹配的文件和目录的内容或属性最后修改时间早于那些文件。
-ctime n匹配的文件和目录的内容和属性最后修改时间在 n*24小时之前。
-empty匹配空文件和目录。
-group name匹配的文件和目录属于一个组。组可以用组名或组 ID 来表示。
-iname pattern就像-name 测试条件,但是不区分大小写。
-inum n匹配的文件的 inode 号是 n。这对于找到某个特殊 inode 的所有硬链接很有帮助。
-mmin n匹配的文件或目录的内容被修改于 n 分钟之前。
-mtime n匹配的文件或目录的内容被修改于 n*24小时之前。
-name pattern用指定的通配符模式匹配的文件和目录。
-newer file匹配的文件和目录的内容早于指定的文件。当编写 shell 脚本,做文件备份时,非常有帮助。 每次你制作一个备份,更新文件(比如说日志),然后使用 find 命令来决定自从上次更新,哪一个文件已经更改了。
-nouser匹配的文件和目录不属于一个有效用户。这可以用来查找 属于删除帐户的文件或监测攻击行为。
-nogroup匹配的文件和目录不属于一个有效的组。
-perm mode匹配的文件和目录的权限已经设置为指定的 mode。mode 可以用 八进制或符号表示法。
-samefile name相似于-inum 测试条件。匹配和文件 name 享有同样 inode 号的文件。
-size n匹配的文件大小为 n。
-type c匹配的文件类型是 c。
-user name匹配的文件或目录属于某个用户。这个用户可以通过用户名或用户 ID 来表示。
 find ~ \( -type f -not -perm 0600 \) -or \( -type d -not -perm 0700 \)

-and -or -not

find预定义操作#

预定义的 find 命令操作

操作描述
-delete删除当前匹配的文件。
-ls对匹配的文件执行等同的 ls -dils 命令。并将结果发送到标准输出。
-print把匹配文件的全路径名输送到标准输出。如果没有指定其它操作,这是 默认操作。
-quit一旦找到一个匹配,退出。
-exec command {} ;-exec rm ’{}’ ’;’ 因为;和{}需要被转义
-ok每次exec会询问用户
-depth指导 find 程序先处理目录中的文件,再处理目录自身。当指定-delete 行为时,会自动 应用这个选项。
-maxdepth levels当执行测试条件和行为的时候,设置 find 程序陷入目录树的最大级别数
-mindepth levels在应用测试条件和行为之前,设置 find 程序陷入目录数的最小级别数。

拓展阅读#

通过把末尾的分号改为加号,就激活了 find 命令的一个功能,把搜索结果结合为一个参数列表, 然后执行一次所期望的命令

xargs它从标准输入接受输入,并把输入转换为一个特定命令的 参数列表

归档和压缩#

执行 gzip 命令时,则原始文件的压缩版会替代原始文件。 相对应的 gunzip 程序被用来把压缩文件复原为没有被压缩的版本。

gzip 选项

选项说明
-c把输出写入到标准输出,并且保留原始文件。也有可能用—stdout 和—to-stdout 选项来指定。gunzip -c data.txt.gz 解压并输出内容
-d解压缩。正如 gunzip 命令一样。也可以用—decompress 或者—uncompress 选项来指定.
-f强制压缩,即使原始文件的压缩文件已经存在了,也要执行。也可以用—force 选项来指定。
-l列出每个被压缩文件的压缩数据。也可用—list 选项。
-r若命令的一个或多个参数是目录,则递归地压缩目录中的文件。也可用—recursive 选项来指定。
-t测试压缩文件的完整性。也可用—test 选项来指定。
-v显示压缩过程中的信息。也可用—verbose 选项来指定。
-number设置压缩指数。number 是一个在1(最快,最小压缩)到9(最慢,最大压缩)之间的整数。 数值1和9也可以各自用—fast 和—best 选项来表示。默认值是整数6。

归档#

收集许多文件捆绑成一个

tar mode[options] pathname...

这里的 mode 是指以下操作模式(这里只展示了一部分,查看 tar 的手册来得到完整列表)之一:

表19-2: tar 模式

模式说明
c为文件和/或目录列表创建归档文件。
x抽取归档文件。
r追加具体的路径到归档文件的末尾。
t列出归档文件的内容。
v详细模式
f指定归档文件的名字
z压缩

如果压缩的时候指定绝对路径,解压的时候会将这个绝对路径一起创建出来

tar xf archive.tar pathname

通过给命令添加末尾的路径名,tar 命令就只会恢复指定的文件。可以指定多个路径名。注意 路径名必须是完全的,精准的相对路径名,就如存储在归档文件中的一样。当指定路径名的时候, 通常不支持通配符;然而,GNU 版本的 tar 命令(在 Linux 发行版中最常出现)通过 —wildcards 选项来 支持通配符。这个例子使用了之前 playground.tar 文件:

cd foo
tar xf ../playground2.tar --wildcards 'home/me/playground/dir-\*/file-A'

tar 命令也可以利用标准输出和输入。这里是一个完整的例子:

[me@linuxbox foo]$ cd
[me@linuxbox ~]$ find playground -name 'file-A' | tar cf - --files-from=-
   | gzip > playground.tgz

在这个例子里面,我们使用 find 程序产生了一个匹配文件列表,然后把它们管道到 tar 命令中。 如果指定了文件名“-”,则其被看作是标准输入或输出,正是所需(顺便说一下,使用“-”来表示 标准输入/输出的惯例,也被大量的其它程序使用)。这个 —file-from 选项(也可以用 -T 来指定) 导致 tar 命令从一个文件而不是命令行来读入它的路径名列表。最后,这个由 tar 命令产生的归档 文件被管道到 gzip 命令中,然后创建了压缩归档文件 playground.tgz。此 .tgz 扩展名是命名 由 gzip 压缩的 tar 文件的常规扩展名。有时候也会使用 .tar.gz 这个扩展名。

我们可以这样简化它:

find playground -name 'file-A' | tar czf playground.tgz -T -

zip#

zip -r playground.zip playground

除非我们包含-r 选项,要不然只有 playground 目录(没有任何它的内容)被存储。虽然会自动添加 .zip 扩展名,但为了清晰起见,我们还是包含文件扩展名。

zip 命令可以接受标准输入,所以它可以被用来压缩其它程序的输出:

ls -l /etc/ | zip ls-etc.zip -在这个例子里,我们把 ls 命令的输出管道到 zip 命令。像 tar 命令,zip 命令把末尾的横杠解释为 “使用标准输入作为输入文件。”

在这个例子里,我们把 ls 命令的输出管道到 zip 命令。像 tar 命令,zip 命令把末尾的横杠解释为 “使用标准输入作为输入文件。

这个 unzip 程序允许它的输出发送到标准输出,当指定了-p 选项之后:

[me@linuxbox ~]$ unzip -p ls-etc.zip | less

rsync 同步#

rsync options source destination

-a 选项(递归和保护文件属性)和-v 选项(冗余输出)

rsync -av playground foo

–delete 这个选项,来删除可能在备份设备中已经存在但却不再存在于源设备中的文件

—rsh=ssh 选项,其指示 rsync 使用 ssh 程序作为它的远程 shell。

正则表达式#

grep 选项

选项描述
-i忽略大小写。不会区分大小写字符。也可用—ignore-case 来指定。
-v不匹配。通常,grep 程序会打印包含匹配项的文本行。这个选项导致 grep 程序 只会不包含匹配项的文本行。也可用—invert-match 来指定。
-c打印匹配的数量(或者是不匹配的数目,若指定了-v 选项),而不是文本行本身。 也可用—count 选项来指定。
-l打印包含匹配项的文件名,而不是文本行本身,也可用—files-with-matches 选项来指定。
-L相似于-l 选项,但是只是打印不包含匹配项的文件名。也可用—files-without-match 来指定。
-n在每个匹配行之前打印出其位于文件中的相应行号。也可用—line-number 选项来指定。
-h应用于多文件搜索,不输出文件名。也可用—no-filename 选项来指定。
-E不加 -E,grep 只支持基本正则,扩展语法要加反斜杠转义,否则不会被识别为正则表达式。加了 -E,扩展正则语法直接可用,写法更简洁。
  1. .表示任意字符

  2. ^表示行首,$表示行尾

  3. 中括号指定 一个字符集合(包含在不加中括号的情况下会被解释为元字符的字符)来被匹配。中括号中开头插入^表示不包含后面字符的

  4. ?可以匹配可以不匹配 *可以匹配任意次,+可以匹配>0次

  5. []表示匹配其中任意一个字符,()表示一个组可以用于匹配和提取,{n, m}至少出现了 n 次,但是不多于 m 次。比如(ab){3}

POSIX 字符集

字符集说明
[:alnum:]字母数字字符。在 ASCII 中,等价于:[A-Za-z0-9]
[:word:]与[:alnum:]相同, 但增加了下划线字符。
[:alpha:]字母字符。在 ASCII 中,等价于:[A-Za-z]
[:blank:]包含空格和 tab 字符。
[:cntrl:]ASCII 的控制码。包含了0到31,和127的 ASCII 字符。
[:digit:]数字0到9
[:graph:]可视字符。在 ASCII 中,它包含33到126的字符。
[:lower:]小写字母。
[:punct:]标点符号字符。在 ASCII 中,等价于:
[:print:]可打印的字符。在[:graph:]中的所有字符,再加上空格字符。
[:space:]空白字符,包括空格,tab,回车,换行,vertical tab, 和 form feed.在 ASCII 中, 等价于:[ \t\r\n\v\f]
[:upper:]大写字母。
[:xdigit:]用来表示十六进制数字的字符。在 ASCII 中,等价于:[0-9A-Fa-f]

文本处理#

  1. cat -n,给文本行添加行号. -s, 禁止输出多个空白行

  2. sort 程序选项

    选项长选项描述
    -b—ignore-leading-blanks默认情况下,对整行进行排序,从每行的第一个字符开始。这个选项导致 sort 程序忽略 每行开头的空格,从第一个非空白字符开始排序。
    -f—ignore-case让排序不区分大小写。
    -n—numeric-sort基于字符串的长度来排序。使用此选项允许根据数字值执行排序,而不是字母值。
    -r—reverse按相反顺序排序。结果按照降序排列,而不是升序。
    -k—key=field1[,field2]对从 field1到 field2之间的字符排序,而不是整个文本行。(field是列号)
    -m—merge把每个参数看作是一个预先排好序的文件。把多个文件合并成一个排好序的文件,而没有执行额外的排序。
    -o—output=file把排好序的输出结果发送到文件,而不是标准输出。
    -t—field-separator=char定义域分隔字符。默认情况下,域由空格或制表符分隔。-t ’:’
sort --key=1,1 --key=2n distros.txt

在第一个 key 选项的实例中, 我们指定了一个字段区域。因为我们只想对第一个字段排序,我们指定了 1,1, 意味着“始于并且结束于第一个字段。”在第二个实例中,我们指定了 2n,意味着第二个字段是排序的键值, 并且按照数值排序。

sort -k 3.7nbr -k 3.1nbr -k 3.4nbr distros.txt
Fedora         10    11/25/2008
Ubuntu         8.10  10/30/2008
SUSE           11.0  06/19/2008
...

通过指定 -k 3.7,我们指示 sort 程序使用一个排序键值,其始于第三个字段中的第七个字符,对应于 年的开头。同样地,我们指定 -k 3.1和 -k 3.4来分离日期中的月和日。 我们也添加了 n 和 r 选项来实现一个逆向的数值排序。这个 b 选项用来删除日期字段中开头的空格( 行与行之间的空格数迥异,因此会影响 sort 程序的输出结果)。

  1.  uniq 选项

    选项说明
    -c输出所有的重复行,并且每行开头显示重复的次数。
    -d只输出重复行,而不是特有的文本行。
    -f n忽略每行开头的 n 个字段,字段之间由空格分隔,正如 sort 程序中的空格分隔符;然而, 不同于 sort 程序,uniq 没有选项来设置备用的字段分隔符。
    -i在比较文本行的时候忽略大小写。
    -s n跳过(忽略)每行开头的 n 个字符。
    -u只是输出独有的文本行。这是默认的。

4 . comm 命令产生了三列输出。第一列包含第一个文件独有的文本行;第二列, 文本行是第二列独有的;第三列包含两个文件共有的文本行。comm 支持 -n 形式的选项,这里 n 代表 1,2 或 3。这些选项使用的时候,指定了要隐藏的列。例如,如果我们只想输出两个文件共享的文本行, 我们将隐藏第一列和第二列的输出结果

脚本#

${filename}1

这样会在文件名后面加个1

如果我们把重定向操作符从 “<<” 改为 “<<-”,shell 会忽略在此 here document 中开头的 tab 字符。 这就能缩进一个 here document,从而提高脚本的可读性:

#!/bin/bash
# Script to retrieve a file via FTP
FTP_SERVER=ftp.nl.debian.org
FTP_PATH=/debian/dists/lenny/main/installer-i386/current/images/cdrom
REMOTE_FILE=debian-cd_info.tar.gz
ftp -n <<- _EOF_
    open $FTP_SERVER
    user anonymous me@linuxbox
    cd $FTP_PATH
    hash
    get $REMOTE_FILE
    bye
_EOF_
ls -l $REMOTE_FILE

 if 语句语法如下:

if commands; then
     commands
[elif commands; then
     commands...]
[else
     commands]
fi

测试整数表达式

表达式如果为真…
integer1 -eq integer2integer1 等于 integer2.
integer1 -ne integer2integer1 不等于 integer2.
integer1 -le integer2integer1 小于或等于 integer2.
integer1 -lt integer2integer1 小于 integer2.
integer1 -ge integer2integer1 大于或等于 integer2.
integer1 -gt integer2integer1 大于 integer2.

测试文件表达式

表达式如果为真
file1 -ef file2file1 和 file2 拥有相同的索引号(通过硬链接两个文件名指向相同的文件)。
file1 -nt file2file1新于 file2。
file1 -ot file2file1早于 file2。
-b filefile 存在并且是一个块(设备)文件。
-c filefile 存在并且是一个字符(设备)文件。
-d filefile 存在并且是一个目录。
-e filefile 存在。
-f filefile 存在并且是一个普通文件。
-g filefile 存在并且设置了组 ID。
-G filefile 存在并且由有效组 ID 拥有。
-k filefile 存在并且设置了它的“sticky bit”。
-L filefile 存在并且是一个符号链接。
-O filefile 存在并且由有效用户 ID 拥有。
-p filefile 存在并且是一个命名管道。
-r filefile 存在并且可读(有效用户有可读权限)。
-s filefile 存在且其长度大于零。
-S filefile 存在且是一个网络 socket。
-t fdfd 是一个定向到终端/从终端定向的文件描述符 。 这可以被用来决定是否重定向了标准输入/输出错误。
-u filefile 存在并且设置了 setuid 位。
-w filefile 存在并且可写(有效用户拥有可写权限)。
-x filefile 存在并且可执行(有效用户有执行/搜索权限)。

测试字符串表达式

表达式如果为真…
stringstring 不为 null。
-n string字符串 string 的长度大于零。
-z string字符串 string 的长度为零。
string1 = string2 string1 == string2string1 和 string2 相同. 单或双等号都可以,不过双等号更受欢迎。
string1 != string2string1 和 string2 不相同。
string1 > string2sting1 排列在 string2 之后。
string1 < string2string1 排列在 string2 之前。

目前的 bash 版本包括一个复合命令,作为加强的 test 命令替代物。它使用以下语法:

[[ expression ]]

这里,类似于 test,expression 是一个表达式,其计算结果为真或假。这个[[ ]]命令非常 相似于 test 命令(它支持所有的表达式),但是增加了一个重要的新的字符串表达式:

string1 =~ regex

其返回值为真,如果 string1匹配扩展的正则表达式 regex。这就为执行比如数据验证等任务提供了许多可能性。 在我们前面的整数表达式示例中,如果常量 INT 包含除了整数之外的任何数据,脚本就会运行失败。这个脚本 需要一种方法来证明此常量包含一个整数。使用 [[ ]] 和 =~ 字符串表达式操作符,我们能够这样来改进脚本:

bash 也提供了 (( )) 复合命名,其有利于操作整数。它支持一套 完整的算术计算

逻辑操作符

操作符测试[[ ]] and (( ))
AND-a&&
OR-o|
NOT!!

可以对表达式使用圆括号,为的是分组。如果不使用括号,那么否定只应用于第一个 表达式,而不是两个组合的表达式。对于 bash 有特殊含义的字符,比如说 ,(,和 ),必须引起来或者是转义。

输入#

read var1 var2 var3 var4 var5

read 选项

选项说明
-a array把输入赋值到数组 array 中,从索引号零开始。我们 将在第36章中讨论数组问题。
-d delimiter用字符串 delimiter 中的第一个字符指示输入结束,而不是一个换行符。
-e使用 Readline 来处理输入。这使得与命令行相同的方式编辑输入。
-n num读取 num 个输入字符,而不是整行。
-p prompt为输入显示提示信息,使用字符串 prompt。
-rRaw mode. 不把反斜杠字符解释为转义字符。
-sSilent mode. 不会在屏幕上显示输入的字符。当输入密码和其它确认信息的时候,这会很有帮助。
-t seconds超时. 几秒钟后终止输入。read 会返回一个非零退出状态,若输入超时。
-u fd使用文件描述符 fd 中的输入,而不是标准输入。

Shell 允许在一个命令之前立即发生一个或多个变量赋值。这些赋值为跟随着的命令更改环境变量。 这个赋值的影响是暂时的;只是在命令存在期间改变环境变量。在这种情况下,IFS 的值改为一个冒号。 另外,我们也可以这样编码:

<<< 操作符指示一个 here 字符串。一个 here 字符串就像一个 here 文档,只是比较简短,由 单个字符串组成。

read不能管道,因为管道会新开一个环境,其不能改变原先环境中的变量

while commands; do commands; done

注意事项#

用""避免不必要的展开

用&&确保上一个命令执行完成后才执行下一个

Linux Command Line
https://tubehao.github.io/blog/posts/tools/linuxcommandline/
Author
tubehao
Published at
2025-08-27