Linux世界的规则

温馨提示:点击页面下方以展开或折叠目录

文章说明
文章作者:鴻塵
文章说明:学习Linux过程中的记录,参考书籍主要有《Linux命令行与shell脚本编程大全(第3版)》,《鸟哥的Linux私房菜(第三版)》系列和《快乐的 Linux 命令行》,参考资料主要有Linux命令大全等。
文章链接:https://hwame.top/20201129/rules-of-linux.html

1.常见Linux目录名称

目录 用途
/ 虚拟目录的根目录,万物起源。通常不会在这里存储文件
/bin 二进制目录,存放许多用户级的GNU工具
/boot 启动目录,包含Linux内核,存放启动文件
/boot/grub/grub.conf or menu.lst,被用来配置启动加载程序
/boot/vmlinuz,Linux 内核
/dev 设备目录,Linux在这里创建设备节点
/etc 系统配置文件目录,也包含一系列的shell脚本
/etc/crontab,定义自动运行的任务
/etc/fstab,包含存储设备的列表,以及与他们相关的挂载点
/etc/passwd,包含用户帐号列表
/home 主目录,Linux在这 里创建用户目录
/lib 库目录,存放系统和应用程序的库文件
/media 媒体目录,可移动媒体设备的常用挂载点
/mnt 挂载目录,另一个可移动媒体设备的常用挂载点
/opt 可选目录,常用于存放第三方软件包和数据文件
/proc 进程目录,存放现有硬件及当前进程的相关信息
/root root用户的主目录
/sbin 系统二进制目录,存放许多GNU管理员级工具
/run 运行目录,存放系统运作时的运行时数据
/srv 服务目录,存放本地服务的相关文件
/sys 系统目录,存放系统硬件信息的相关文件
/tmp 临时目录,可以在该目录中创建和删除临时工作文件
/usr 用户二进制目录,大量用户级的GNU工具和数据文件都存储在这里,它可能是Linux系统中最大的一个
/usr/bin,包含系统安装的可执行程序,通常会包含许多程序
/usr/lib,包含由/usr/bin目录中的程序所用的共享库
/usr/local,非系统发行版自带却打算让系统使用的程序的安装目录
/usr/sbin,包含许多系统管理程序
/usr/share,包含许多由/usr/bin目录中的程序使用的共享数据,其中包括像默认的配置文件、图标、桌面背景、音频文件等等
/usr/share/doc,大多数安装在系统中的软件包会包含一些文档
/var 可变目录,用以存放经常变化的文件,比如日志文件

2.通配符

2.1.通配符

通配符 意义
* 匹配任意多个字符(包括零个或一个)
? 匹配任意一个字符(不包括零个)
[characters] 匹配任意一个属于字符集中的字符
[!characters] 匹配任意一个不是字符集中的字符
[[:class:]] 匹配任意一个属于指定字符类中的字符

注意:不同于正则表达式中的.,此处的.仍表示其自身。

参考「通配符」和「正则表达式」的区别
通配符是系统级的,多用于文件名上,如findlscp等;
正则表达式则需要相关工具的支持,如egrepawkviperl等,多用于针对文件内容的文本过滤工具,如awksed等。

2.2.常用的字符类

通配符 意义
[:alnum:] 匹配任意一个字母或数字
[:alpha:] 匹配任意一个字母
[:digit:] 匹配任意一个数字
[:lower:] 匹配任意一个小写字母
[:upper:] 匹配任意一个大写字母

2.3.通配符范例

模式 匹配对象
* 所有文件
g* 文件名以g开头的文件
b*.txt b开头,中间任意多个($\ge 0$)字符,并以.txt结尾的文件
Data??? Data开头,其后紧接着 3 个字符的文件
[abc]* 文件名以abc开头的文件
BACK.[0-9][0-9] BACK.开头并紧接2个数字的文件
[[:upper:]]* 以大写字母开头的文件
[![:digit:]]* 不以数字开头的文件
*[[:lower:]123] 以小写字母、123四种之一结尾的文件

3.命令表示法

很多时候我们需要参考某个命令的用法,例如用command --helpman command查看帮助文档,但是选项参数太多,语法规则不知道意义,以下是简单介绍各符号的意义:

符号 意义
[] 表示可选的项目
<> 位置参数
() 必需
表示互斥选项
... 表示参数可重复

详细说明请参考:

4.文件描述符与重定向

Linux中万物皆文件,用文件描述符(file descriptor)来标识每个文件对象。每个进程一次最多可以有九个文件描述符。出于特殊目的,bash shell保留了前三个文件描述符:

文件描述符 缩写 描述
0 STDIN 标准输入
1 STDOUT 标准输出
2 STDERR 标准错误

默认情况下,STDERR文件描述符会和STDOUT文件描述符指向同样的地方(尽管分配给它们的文件描述符值不同)。也就是说,默认情况下,错误消息也会输出到显示器输出中。但STDERR并不会随着STDOUT的重定向而发生改变,例如将STDOUT重定向到某文件但是STDERR依然会打印到屏幕。

  • 只重定向错误:只重定向错误消息需要将该文件描述符值放在重定向符号前,该值必须紧紧地放在重定向符号前,否则不会工作:command 2> error.txt。注意,shell会只重定向错误消息,正常输出仍会显示在屏幕上。
  • 重定向错误和数据:如果想重定向错误和正常输出,必须用两个重定向符号。需要在符号前面放上待重定向数据所对应的文件描述符,然后指向用于保存数据的输出文件:command 2> error.txt 1> output.txt。可以用这种方法将脚本的正常输出和脚本生成的错误消息分离开来。如果想将错误和正常输出重定向到同一个输出文件,则需使用特殊的重定向符号&>,即command &> allinfo.txt。注意,当使用&>符时命令生成的所有输出都会发送到同一位置,包括数据和错误,但是错误消息具有更高的优先级。



  • 在脚本中重定向输出:包括「临时重定向行输出」和「永久重定向脚本中的所有命令」。
    • 使用输出重定向符来将输出信息重定向到STDERR文件描述符,在重定向到文件描述符时必须在文件描述符数字之前加一个&command >&2。因为Linux默认会将STDERR导向STDOUT,因此直接运行没有区别,必须使用./mz.sh 2> stderr.txt才能将脚本中所有导向STDERR的文本重定向到txt文件。见下例:
      1
      2
      3
      4
      5
      6
      #!/bin/bash
      echo "This is an error" >&2
      echo "This is normal output"

      # 执行将输出两句:./mz.sh
      # 执行将输出一句:./mz.sh 2> stderr.txt
    • 如果脚本中有大量数据需要重定向,那么每句都重定向会很烦琐,因此可以用exec命令告诉shell在脚本执行期间重定向某个特定文件描述符,见下例:
      1
      2
      3
      4
      5
      6
      7
      8
      #!/bin/bash
      exec 2>testerror
      echo "This is the start of the script"
      echo "now redirecting all output to another location"

      exec 1>testout
      echo "This output should go to the testout file"
      echo "but this should go to the testerror file" >&2
      运行该脚本,四个echo语句中的一二句会打印到屏幕,第三句重定向到testout,第四句重定向到testerror
      注意:一旦重定向了STDOUTSTDERR,就很难再将它们重定向回原来的位置。如果你需要在重定向中来回切换的话,见下文。
  • 在脚本中重定向输入:exec命令允许你将STDIN重定向到Linux系统上的文件中:exec 0< stdin.txt。这个命令会告诉shell它应该从文件stdin.txt中获得输入,而不是STDIN。这个重定向只要在脚本需要输入时就会作用。见下例:
    read命令读取用户在键盘上输入的数据。将STDIN重定向到文件后,当read命令试图从STDIN读入数据时,它会到文件去取数据,而不是键盘。
    1
    2
    3
    4
    5
    6
    7
    8
    #!/bin/bash
    exec 0< testfile
    count=1
    while read line
    do
    echo "Line #$count: $line"
    count=$[ $count + 1 ]
    done

在shell中最多可以有9个打开的文件描述符。其他6个从3~8的文件描述符均可用作输入或输出重定向。你可以将这些文件描述符中的任意一个分配给文件,然后在脚本中使用它们。
你可以分配另外一个文件描述符给标准文件描述符,反之亦然。这意味着你可以将STDOUT的原来位置重定向到另一个文件描述符,然后再利用该文件描述符重定向回STDOUT。见下例:

1
2
3
4
5
6
7
8
#!/bin/bash
exec 3>&1
exec 1>testout
echo "This should store in the output file"
echo "along with this line."

exec 1>&3
echo "Now things should be back to normal"

首先,脚本将文件描述符3重定向到文件描述符1(STDOUT)的当前位置,这意味着任何发送给文件描述符3的输出都将出现在显示器上。第二个exec命令将STDOUT重定向到文件, shell现在会将发送给STDOUT的输出直接重定向到输出文件中。但是,文件描述符3仍然指向STDOUT原来的位置,也就是显示器。如果此时将输出数据发送给文件描述符3,它仍然会出现在显示器上,尽管STDOUT已经被重定向了。在向STDOUT(现在指向一个文件)发送一些输出之后,脚本将STDOUT重定向到文件描述符3的当前位置(现在仍然是显示器)。这意味着现在STDOUT又指向了它原来的位置:显示器。
这个方法可能有点叫人困惑,但这是一种在脚本中临时重定向输出,然后恢复默认输出设置的常用方法。

同样,在重定向到文件之前,先将STDIN文件描述符保存到另外一个文件描述符,然后在读取完文件之后再将STDIN恢复到它原来的位置。见下例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash
exec 6<&0
exec 0< testfile
count=1
while read line; do
echo "Line #$count: $line"
count=$[ $count + 1 ]
done
exec 0<&6
read -p "Are you done now? " answer
case $answer in
Y|y) echo "Goodbye";;
N|n) echo "Sorry, this is the end.";;
esac

文件描述符6用来保存STDIN的位置,然后脚本将STDIN重定向到一个文件testfileread命令的所有输入都来自重定向后的STDIN(也就是输入文件)。在读取了所有行之后,脚本会将STDIN重定向到文件描述符6,从而将STDIN恢复到原先的位置。该脚本用了另外一个read命令来测试STDIN是否恢复正常了,这次它会等待键盘的输入。

5.待续