Linux操作系统笔记

本文最后更新于:2023年12月29日 上午

Linux操作系统笔记

文件与目录基本操作

文件名长度

• 一般允许1-255个字符

• 有些UNIX不支持长文件名,但至少支持1-14个字符

取名的合法字符

• 除斜线(“/“)外的所有字符都是命名的合法字符

• 不可打印字符也可以做文件名(除了字节0)

• 斜线(“/“)留作路径名分隔符

• 建议文件名中只包含字母、数字和下划线

touch命令

touch 是一个在 Unix 和类 Unix 操作系统中常用的命令,用于创建空文件或者更新文件的访问和修改时间戳。以下是 touch 命令的基本用法和选项:

基本用法:
1
touch [选项] 文件名
选项:
  1. -a,–time=atime,–time=access,–time=use:只更改访问时间。

    1
    touch -a filename
  2. -c,–no-create:不创建任何文件。

    1
    touch -c filename
  3. -d,–date=字符串:使用指定的日期时间字符串,而不是当前时间。

    1
    touch -d "2023-01-01 12:00:00" filename
  4. -m,–time=mtime,–time=modification:只更改修改时间。

    1
    touch -m filename
  5. -t,–time=时间戳:使用指定的时间戳,格式为 [[CC]YY]MMDDhhmm[.ss]

    1
    touch -t 202301011200.00 filename
  6. –help:显示帮助信息。

    1
    touch --help
  7. –version:显示版本信息。

    1
    touch --version
示例:
  1. 创建一个新文件:

    1
    touch newfile.txt
  2. 更改文件的访问和修改时间:

    1
    touch filename
  3. 使用指定的日期时间字符串:

    1
    touch -d "2023-01-01 12:00:00" filename
  4. 使用指定的时间戳:

    1
    touch -t 202301011200.00 filename
  5. 只更新访问时间:

    1
    touch -a filename
  6. 只更新修改时间:

    1
    touch -m filename

touch 命令的主要功能是更新文件的时间戳,但它也可以用来创建新文件,如果文件不存在的话。

mkdir命令

mkdir 是用于在 Unix 和类 Unix 操作系统中创建目录(文件夹)的命令。以下是 mkdir 命令的基本用法和选项:

基本用法:
1
mkdir [选项] 目录名
选项:
  1. -m,–mode=模式:设置权限模式(类似于 chmod 命令)。

    1
    mkdir -m 755 mydirectory
  2. -p,–parents:递归创建目录,如果上层目录不存在也会创建。

    1
    mkdir -p /path/to/my/directory
  3. –help:显示帮助信息。

    1
    mkdir --help
  4. –version:显示版本信息。

    1
    mkdir --version
示例:
  1. 创建一个新目录:

    1
    mkdir mydirectory
  2. 设置权限模式:

    1
    mkdir -m 755 mydirectory
  3. 递归创建目录及其父目录:

    1
    mkdir -p /path/to/my/directory

mkdir 命令是创建目录的标准工具。通过指定目录名,您可以创建一个新的目录。如果要创建多级目录,可以使用 -p 选项,这样如果上层目录不存在,也会被创建。

cp命令

1
2
3
4
5
6
7
8
cp fly fly2 #复制文件
cp -i fly fly2 #复制时询问是否覆盖已有文件
cp -p fly fly3 #复制时保持文件属性不变
cp fly butterfly doc #复制多个文件至一个目录
cp fly bak/fly.bak
cp doc/* bak #复制doc中的所有文件到bak中
cp -R /usr/share/doc/pam-1.1.8/ doc #递归复制目录
cp -a /usr/share/doc/pam-1.1.8/ doc #同上且保持文件属性

mv命令

mv 命令是在 Unix 和类 Unix 操作系统中用于移动或重命名文件或目录的命令。以下是 mv 命令的基本用法和选项:

基本用法:
1
mv [选项] 源文件/目录 目标文件/目录
  1. 移动文件到另一个目录:

    1
    mv file.txt /path/to/destination/
  2. 重命名文件:

    1
    mv oldfile.txt newfile.txt
  3. 移动并覆盖目标文件(无提示):

    1
    mv -f source.txt /path/to/destination/
  4. 移动文件并为目标文件创建备份:

    1
    mv -b file.txt /path/to/backup/
  5. 交互式地移动文件,避免覆盖目标文件:

    1
    mv -i file.txt /path/to/destination/
  6. 仅在源文件较新或目标文件不存在时执行移动操作:

    1
    mv -u file.txt /path/to/destination/

mv 命令不仅可以用于移动文件,还可以用于重命名文件。其选项提供了一些额外的控制,例如备份、强制覆盖和交互式提示等。

rm命令

1
2
3
rm doc/fly #删除文件
rm -i doc/fly{2,4} #删除前询问
rm -f doc/fly4 #强行删除

rmdir命令

1
2
3
4
5
mkdir -p a1/b1/c1 a2/b2/c2 a3/b3/c3
rmdir a1/b1/c1 #删除空目录
rmdir -p a2/b2/c2 #删除多层空目录
rmdir -p a3/b3 #error
rm -rf a3 #删除目录及其内的文件

wc命令

wc(word count)命令是用于计算文件中字数、行数和字符数的命令。

基本用法:
1
wc [选项] 文件名
选项:
  1. -c,–bytes: 打印文件的字节数。

    1
    wc -c filename
  2. -w,–words: 打印文件的字数。

    1
    wc -w filename
  3. -l,–lines: 打印文件的行数。

    1
    wc -l filename
  4. –help: 显示帮助信息。

    1
    wc --help
  5. –version: 显示版本信息。

    1
    wc --version
示例:
  1. 计算文件的字节数、字数和行数:

    1
    wc filename
  2. 只显示文件的字节数:

    1
    wc -c filename
  3. 只显示文件的字数:

    1
    wc -w filename
  4. 只显示文件的行数:

    1
    wc -l filename
  5. 同时统计多个文件的字节数、字数和行数:

    1
    wc file1.txt file2.txt

搜索文件

find命令

find 命令是查找文件和目录的命令。它支持强大的搜索功能,

基本用法:
1
find 目录 -选项 [条件]
常见选项和条件:
  1. -name “模式”: 按文件名进行匹配,可以使用通配符。

    1
    find /path/to/search -name "*.txt"
  2. -type 类型: 按文件类型进行匹配,如 f 表示文件,d 表示目录。

    1
    find /path/to/search -type f
  3. -size [+/-]大小: 按文件大小进行匹配,加号表示大于,减号表示小于,没有符号表示等于。

    1
    find /path/to/search -size +1M
  4. -mtime [+/-]天数: 按文件修改时间进行匹配,加号表示更早,减号表示更近。

    1
    find /path/to/search -mtime -7
  5. -exec 命令 {} ;: 对匹配到的文件执行指定的命令。

    1
    find /path/to/search -name "*.log" -exec rm {} \;
  6. -print: 将匹配到的文件路径打印到标准输出。

    1
    find /path/to/search -name "*.txt" -print
  7. -maxdepth 深度: 限制查找的最大深度。

    1
    find /path/to/search -name "*.txt" -maxdepth 2
  8. -mindepth 深度: 限制查找的最小深度。

    1
    find /path/to/search -name "*.txt" -mindepth 2
示例:
  1. 查找所有以 .txt 结尾的文件:

    1
    find /path/to/search -name "*.txt"
  2. 查找文件并执行操作(例如删除):

    1
    find /path/to/search -name "*.log" -exec rm {} \;
  3. 查找指定类型的文件:

    1
    find /path/to/search -type f
  4. 查找大于 1MB 的文件:

    1
    find /path/to/search -size +1M
  5. 查找最近 7 天内修改过的文件:

    1
    find /path/to/search -mtime -7

xargs

xargs 是一个命令,用于从标准输入或者其他命令的输出中读取数据,并将其作为参数传递给指定的命令。xargs 可以帮助处理由其他命令生成的大量输入,并将其转换为命令行参数。

基本用法:
1
command | xargs [选项] 命令
常见选项:
  1. -0,–null: 使用空字符(null)作为定界符,用于处理文件名中可能包含空格等特殊字符的情况。

    1
    find /path/to/files -type f -print0 | xargs -0 rm
  2. -n 数目,–max-args=数目: 指定每个命令行调用使用的参数的最大数目。

    1
    ls | xargs -n 2
  3. -i,–replace[=替代字符串]: 使用替代字符串替代命令中的 {},或者使用指定的替代字符串。

    1
    echo "file1 file2 file3" | xargs -i cp {} /destination/path
  4. -p,–interactive: 在执行命令之前,提示用户确认是否继续。

    1
    find /path/to/files -type f | xargs -p rm
  5. –help: 显示帮助信息。

    1
    xargs --help
  6. –version: 显示版本信息。

    1
    xargs --version
示例:
  1. 使用 xargs 将文件列表传递给 rm 命令删除文件:

    1
    find /path/to/files -name "*.txt" | xargs rm
  2. 使用 -execxargs 结合,删除大量文件:

    1
    find /path/to/files -name "*.log" -exec rm {} +
  3. 使用 xargs 处理包含空格的文件名:

    1
    find /path/to/files -type f -print0 | xargs -0 rm
  4. 使用 xargs 交互式地执行命令:

    1
    find /path/to/files -name "*.tmp" | xargs -p rm
  5. 使用 -i 替代字符串:

    1
    echo "file1 file2 file3" | xargs -i cp {} /destination/path

find与xargs协作

1
2
3
4
5
6
7
8
9
# 默认情况下xargs会将每个输入作为参数附加到命令最后
find . -type f -name "*.txt" | xargs rm -f
# 要把输入放在命令的其他位置,需用占位符,-I可指定占位符
find . -name '*.mp3' | xargs -I{} mv {} songs
find . -name '*.mp3' | xargs -Ix mv x songs # 同上
#为处理文件名含有特殊字符(如空格)的情况,一般会结合find的-print0
和xargs的-0来避免出错,find的-print0将用'\0'作为分隔符分割每个文
件名,而xargs的-0则以'\0'作为分隔符来读取文件名。
find . -name '*.mp3' -print0 | xargs -Imp3 -0 mv mp3 songs

压缩和解压缩文件

1. tar 命令(打包/解包)

  • 打包文件或目录:

    1
    tar -cvf archive.tar file1 file2 directory1
  • 解包文件:

    1
    tar -xvf archive.tar
  • 打包并压缩(使用 gzip):

    1
    tar -czvf archive.tar.gz file1 file2 directory1
  • 解压缩并解包(使用 gzip):

    1
    tar -xzvf archive.tar.gz

2. gzip 和 gunzip 命令

  • 压缩文件:

    1
    gzip filename
  • 解压缩文件:

    1
    gunzip filename.gz

3. bzip2 和 bunzip2 命令

  • 压缩文件:

    1
    bzip2 filename
  • 解压缩文件:

    1
    bunzip2 filename.bz2

4. zip 和 unzip 命令

  • 压缩文件或目录:

    1
    zip archive.zip file1 file2 directory1
  • 解压缩文件或目录:

    1
    unzip archive.zip

示例:

  1. 使用 tar 打包和解包:

    1
    2
    3
    4
    5
    # 打包
    tar -cvf archive.tar file1 file2 directory1

    # 解包
    tar -xvf archive.tar
  2. 使用 tar 打包并压缩(gzip):

    1
    2
    3
    4
    5
    # 打包并压缩
    tar -czvf archive.tar.gz file1 file2 directory1

    # 解压缩并解包
    tar -xzvf archive.tar.gz
  3. 使用 gzip 进行压缩和解压缩:

    1
    2
    3
    4
    5
    # 压缩
    gzip filename

    # 解压缩
    gunzip filename.gz
  4. 使用 bzip2 进行压缩和解压缩:

    1
    2
    3
    4
    5
    # 压缩
    bzip2 filename

    # 解压缩
    bunzip2 filename.bz2
  5. 使用 zip 进行压缩和解压缩:

    1
    2
    3
    4
    5
    # 压缩
    zip archive.zip file1 file2 directory1

    # 解压缩
    unzip archive.zip

分割与合并文件

split

有时网站、U盘等对文件大小有限制,需要把大文件 拆分成更小的文件。

1
2
3
4
5
6
7
8
9
10
11
12
tar -czf bak.tar.gz /usr/share/doc/
split -b 5M bak.tar.gz # 以5M大小为单位进行拆分
# 默认情况下拆分得到的文件名以x开头,后面跟从aa开始的两位字母
split -b 5M -d -a 3 bak.tar.gz docs.tar.gz.part.
# -d 使用数字后缀
# -a 3 数字后缀长度为3位
# 拆分后的文件名均以doc.tar.gz.part.开头
cat docs.* >docs.tar.gz # 合并
cmp bak.tar.gz docs.tar.gz # 比较
echo 'passwd 123456' >secret
cat sunrise.jpg secret >sun.jpg
tail sun.jpg

过滤器

0x01.grep 行过滤

grep可以过滤行

grep选项:

  • -i 忽略大小写
  • -n 添加行号
  • -v 反向过滤,grep -v 'abc' myfile 过滤出除了有abc的行
  • -c 记录出符合的行中总字符数
基本正则表达式 grep
  • . 表示单个任意字符(换行符除外)

  • […] 表示单个括号中的任意字符

  • x* 表示x出现0次或0次以上

  • ^x 锚定行首字符x,其中^代表行首

  • x$ 锚定行尾字符x,其中$代表行尾

扩展正则表达式 egrep

grep默认把 ERE 元字符按普通字符处理,在其 前面有反斜杠时才按元字符处理,这一点正好与 扩展正则表达式元字符相反!

扩展正则表达式元字符 : ?、+、|、{ }、( )

• grep -E

• egrep

x+ 表示 x 出现 1 次以上
1
2
3
$ grep '^[0-9]\+$' rfile
$ grep -E '^[0-9]+$' rfile
$ egrep '^[0-9]+$' rfile
x? 表示 x 出现 0 次或 1 次
1
2
grep '^[0-9]*\.\?[0-9]\+$' rfile
grep -E '^[0-9]*.?[0-9]+$' rfile
x|y 表示 x 或 y
1
2
grep 'html\|HTML' rfile  # 注意在|两侧不能加空格
grep -E 'html|HTML' rfile
x{n} 表示 x 正好出现 n 次
x{n,} 表示 x 出现 n 次以上
x{m,n} 表示 x 出现 m 到 n 次 (m<n)

0x02.cut 列过滤

cut可以过滤列,

cut选项:

  • -c 指定提取的字符列表,-c3 表示提取每列的第3个字符
  • -f 提取指定的字段列表 ,-f1,3 表示提取第1和第3个字段
  • -d 指定字段的分隔符,-d ',' 以逗号分隔字段
  • -b 按字节位置提取文件内容,可以指定一个范围
image-20231006204806001

0x03.tr 字符转换

tr只能通过stdin标准输入

小写转大写
1
2
[f23a16@localhost ~]$ echo "leekos haha" | tr 'a-z' 'A-Z'
LEEKOS HAHA
空格转tab
1
2
3
4
5
6
7
8
[f23a16@localhost ~]$ cat myfile 
like man 20 182
leekos booy 19 180
bob male 22 172
[f23a16@localhost ~]$ tr ' ' '\t' < myfile
like man 20 182
leekos booy 19 180
bob male 22 172
tr -d 删除字符
1
2
3
4
[f23a16@localhost ~]$ tr -d '0-9' < myfile   # 删除数字
like man
leekos booy
bob male
tr -c 取反

tr -c 可以进行取指定字符的补集,类似正则的^

1
2
[f23a16@localhost ~]$ tr -cd '0-9' < myfile   # 使用-d删除字符,-c取反,可以删除非数字
201821918022172[f23a16@localhost ~]$
tr -s 压缩重复字符
1
2
[f23a16@localhost ~]$  echo "flaaaaaag is here" | tr -s 'a'  # 压缩重复的a
flag is here

0x04.sort 排序

sort命令用于对文本文件的行进行排序操作。它可以按照不同的排序规则和顺序对行进行排序,并将结果输出到标准输出或指定的文件中。

以下是sort命令的一些常见选项:

  • -r, --reverse:以逆序排序,即降序排序。
  • -n, --numeric-sort:按照数值进行排序而不是按照字典顺序。适用于包含数值的行。
  • -f, --ignore-case:在排序时忽略大小写,即不区分大小写进行排序。
  • -u, --unique:去除重复的行,仅保留唯一的行。
  • -k, --key=KEYDEF:按照指定的键定义进行排序。可以指定多个键定义以进行复合排序。
  • -t, --field-separator=SEP:指定字段分隔符。默认情况下,字段分隔符是空白字符(空格或制表符)。
1
2
3
4
$ sort booklist #按字典序排序
$ sort -t^ -k3 booklist #按出版年份排序
$ sort -t^ -k4.2 booklist #按价格排序 !?
$ sort -t^ -k4.2 -nr booklist #按价格从高到低排序
1
2
3
4
5
6
7
8
[f23a16@localhost ~]$ cat booklist 
All the light we cannot see^Anthony Doerr^2014^$15.29
Red queen^Victoria Aveyard^2015^$10.58
Saga,Vol.1^Brian K. Vaughan^2012^$8.46
The blood of Olympus^Pick Piordan^2014^$11.99
The day the crayons quit^Drew Daywalt^2013^$10.32
The girl on the train^Paula Hawkins^2015^$14.01
Winter(Lunar)^Marissa Meyer^2015^$13.84
sort -r -t -k
  • -r 降序排列
  • -t 指定字段分隔符
  • -k 指定排序字段
1
2
3
4
5
6
7
8
[f23a16@localhost ~]$ sort -rt^ -k3 booklist  # 降序排列,以^分隔字段,以第三列排序
The girl on the train^Paula Hawkins^2015^$14.01
Winter(Lunar)^Marissa Meyer^2015^$13.84
Red queen^Victoria Aveyard^2015^$10.58
All the light we cannot see^Anthony Doerr^2014^$15.29
The blood of Olympus^Pick Piordan^2014^$11.99
The day the crayons quit^Drew Daywalt^2013^$10.32
Saga,Vol.1^Brian K. Vaughan^2012^$8.46
sort -k -n
  • -n 以数值大小排序,而不是以字典排序
  • -k 指定排序字段,加小数点,表示从第几位开始算

sort -n -t^ -k4.2 booklist

-n表示以数值大小排序,-k4.2表示以第4个字段的第2位排序

image-20231006212444700
sort 可通过多个-k多列排序

image-20231006213654589

  • -k1.3,1.4:这个键定义表示按照第一个字段的第三个字符和第四个字符进行排序。它将会对这个范围内的字符进行排序,而忽略其他字符。
  • -k3nr:这个键定义表示按照第三个字段进行逆序排序。n选项指示对字段进行数值排序,r选项表示逆序排序。
  • -k2nr:这个键定义表示按照第二个字段进行逆序排序,同样使用了n选项进行数值排序和r选项进行逆序排序。

整个命令的作用是首先按照第一个字段的第三个和第四个字符进行排序,然后在相同的排序结果中,按照第三个字段进行逆序排序,最后在相同的排序结果中,按照第二个字段进行逆序排序。

0x05.uniq

  • -c, --count:在输出中显示每行重复出现的次数。
  • -d, --repeated:仅显示重复的行。
  • -u, --unique:仅显示不重复的行。
  • -i, --ignore-case:在比较行时忽略大小写。
  • -f, --skip-fields=N:跳过前面的 N 个字段,仅考虑从第 N+1 个字段开始的内容。
  • -s, --skip-chars=N:跳过前面的 N 个字符,仅考虑从第 N+1 个字符开始的内容。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
[f23a16@localhost ~]$ cat numlist 
123
56
123
123
78
78
30
[f23a16@localhost ~]$ uniq numlist
123
56
123
78
30
[f23a16@localhost ~]$ sort numlist
123
123
123
30
56
78
78
[f23a16@localhost ~]$ sort numlist | uniq
123
30
56
78
[f23a16@localhost ~]$ sort numlist | uniq -d
123
78
[f23a16@localhost ~]$ sort numlist | uniq -u
30
56
[f23a16@localhost ~]$ sort numlist | uniq -c
3 123
1 30
1 56
2 78

sed

sed是一种流编辑器(stream editor),在Unix和类Unix系统中广泛使用。它用于处理文本流,可以在读取输入流时对文本进行转换和编辑,然后将结果输出到标准输出流。

sed通过一系列编辑命令来实现对文本的处理。这些命令可以用于插入、删除、替换和转换文本,以及执行其他各种编辑操作。sed的编辑命令可以通过脚本文件或命令行直接提供。

sed命令格式
1
2
3
$ sed [选项]... '脚本' 文件...
$ sed [选项]... -e '脚本1' -e '脚本2'... 文件...
$ sed [选项]... -f 脚本文件 文件...

-e 可以用来执行多个脚本,-f代表从脚本文件中执行脚本

sed工作原理
  1. sed从输入流中逐行读取文本。
  2. 对于每一行,sed检查是否有与之匹配的编辑命令。
  3. 如果有匹配的命令,sed执行该命令对文本进行转换和编辑。
  4. sed将转换后的文本输出到标准输出流。
  5. 重复步骤2到步骤4,直到处理完所有的输入行

image-20231013081134585

sed常用选项
  1. -n:禁止自动打印模式空间内容。默认情况下,sed会将每一行的内容打印到标准输出流,但使用-n选项后,只有通过p命令显式指定打印的行才会被输出。
  2. -i:直接在原始文件中进行编辑,即原地修改文件。使用此选项后,sed会将编辑后的结果直接写回到原始文件中,而不是将结果输出到标准输出流。
  3. -e script:在命令行中指定编辑脚本。使用此选项可以直接在命令行中提供一系列编辑命令,而不是使用脚本文件。
  4. -f script-file:从指定的脚本文件中读取编辑命令。使用此选项可以将编辑命令保存在一个脚本文件中,然后通过-f选项指定该文件来执行编辑操作。
  5. -r:启用扩展正则表达式语法。默认情况下,sed使用基本正则表达式语法,但使用-r选项后,可以使用更强大的扩展正则表达式语法。
  6. -s:对每个输入文件分别处理。默认情况下,sed会将所有输入文件视为单个连续的文本流进行处理,而使用-s选项后,sed会将每个输入文件视为独立的文本流进行处理。
  7. -u:即时刷新输出。默认情况下,sed会将输出缓冲起来,然后一次性输出。使用-u选项后,sed会立即刷新输出,以实现更及时的输出。
sed行选择

命令前面可以附加地址作为执行条件

1
2
3
4
5
6
n #第n行
m~n #第m+kn行,如1~2表示所有奇数行
$ #末行
/re/ #与正则表达式re匹配的行
\%re% #同上,%可替换为其他字符
/re/! #不与re匹配的行
  1. 第n行:

    • 选择第5行并打印:

      1
      sed '5p' file.txt
  2. 第m+kn行:

    • 选择所有奇数行并打印:

      1
      sed '1~2p' file.txt
    • 选择所有3的倍数行并打印:

      1
      sed '1~3p' file.txt
  3. 末行:

    • 选择末行并打印:

      1
      sed '$p' file.txt
  4. 与正则表达式re匹配的行:

    • 选择包含单词”apple”的行并打印:

      1
      sed '/apple/p' file.txt
  5. 与正则表达式re匹配的行(使用%作为定界符):

    • 选择以”example”开头的行并打印:

      1
      sed '\%^example%p' file.txt
  6. 不与正则表达式re匹配的行:

    • 选择不包含单词”apple”的行并打印:

      1
      sed '/apple/!p' file.txt
sed范围选择
1
2
3
4
m,n #从第m行至第n行
n,/re/ #从第n行往后至与regexp匹配的第一行
/re1/,/re2/ #从匹配re1的行开始到匹配re2的第一行为止
m,n! #从m~n行之外的行

当使用sed时,以下是使用给范围选择的示例:

  1. 从第m行至第n行:

    • 选择从第3行到第7行并打印:

      1
      sed '3,7p' file.txt
  2. 从第n行往后至与正则表达式re匹配的第一行:

    • 选择从第5行往后,直到遇到包含单词”apple”的第一行,并打印:

      1
      sed '5,/apple/p' file.txt
  3. 从匹配re1的行开始到匹配re2的第一行为止:

    • 选择从包含”start”的行开始,一直到遇到包含”end”的第一行,并打印:

      1
      sed '/start/,/end/p' file.txt
  4. 从m~n行之外的行:

    • 选择不在第2行到第5行范围内的行,并打印:

      1
      sed '2,5!p' file.txt
sed常用命令
  1. #:注释命令,用于添加注释,对脚本没有实际影响。
  • 示例:

    1
    sed 's/old/new/' file.txt  # 替换文件中的字符串,忽略注释行
  1. q:退出命令,用于在满足条件后退出sed的执行。

    • 示例:

      1
      sed '/pattern/q' file.txt  # 匹配到指定模式后退出,并打印之前的内容
  2. d:删除命令,用于删除模式空间的内容,并立即开始新的循环。

    • 示例:

      1
      sed '/pattern/d' file.txt  # 删除包含指定模式的行
  3. p:打印命令,用于打印模式空间的内容。

  • 示例:

    1
    sed -n '2,5p' file.txt  # 打印文件中第2行到第5行的内容
  1. n:读取下一行命令,用于替换模式空间的内容为文件的下一行。

    • 示例:

      1
      sed -n '/start/,/end/p;n' file.txt

    这个示例将打印位于”start”和”end”之间的行,并在打印后读取下一行。这样可以确保在每次打印匹配行后,都会继续处理下一行

  2. {cmd1; cmd2; ...}:命令组,用于在地址匹配时执行多个命令。

    • 示例:

      1
      sed '/pattern/{s/foo/bar/; s/apple/orange/}' file.txt  # 匹配到指定模式后执行多个替换操作
sed示例
1
2
3
4
5
6
7
8
9
10
11
12
$ sed '' students.db #空脚本,默认输出
$ sed -n '' students.db #空脚本,关闭默认输出
$ sed -n '1,$p' students.db #显式打印每一行
$ sed '5q' students.db #打印前10行后退出
$ sed -n '$p' students.db #打印最后一行
$ sed '/^$/d' .bash_profile #删除空行
$ sed '\|^#|d' .bash_profile #删除以#开头的行
$ sed -n 'n;p' students.db #打印偶数行
$ sed -n -e 'n' -e 'p' students.db #同上
$ sed '1~2d' students.db #同上
$ sed '2~2!d' students.db #同上
$ sed -n '2,10{n;p}' students.db #从第3行开始隔行打印
sed s命令

sed中的s命令是用于替换字符串的常见命令。它的语法为:

1
sed 's/old/new/' file.txt

其中,old是要替换的旧字符串,new是替换为的新字符串。s命令默认只替换每行中第一个匹配的字符串,如果要替换所有匹配的字符串,可以添加g标志(全局替换):

1
sed 's/old/new/g' file.txt

以下是一些示例,展示了s命令的用法:

  1. 替换单个字符串:

    • 将文件中的所有”apple”替换为”orange”:

      1
      sed 's/apple/orange/g' file.txt
  2. 使用正则表达式进行替换:

    • 将文件中以”apple”开头的单词替换为”orange”:

      1
      sed 's/^apple/orange/g' file.txt
  3. 引用捕获组进行替换:

    • 将文件中的日期格式”DD/MM/YYYY”替换为”YYYY-MM-DD”:

      1
      sed 's/\([0-9]\{2\}\)\/\([0-9]\{2\}\)\/\([0-9]\{4\}\)/\3-\2-\1/g' file.txt
  4. 替换特定行中的字符串:

    • 只将第5行中的”apple”替换为”orange”:

      1
      sed '5s/apple/orange/g' file.txt

sed高级

N
  • 读下一行
  • 若读取失败则直接退出sed(不再执行其后的命令)
  • 若读取成功则在模式空间尾部添加换行符\n,并将 新行附加在后面
image-20231013083550354
P

打印模式空间内容至第一个换行符 (包括该换行符)

image-20231013083615416
D

如果模式空间中不含\n,则与d命令相同,否则删除 模式空间中直到第一个\n的内容(包含该\n),然后对 模式空间中的剩余内容执行新一轮循环(不读入新行)

image-20231013083653831
sed高级命令示例
1
sed 'N;D' students.db 	#打印末行
image-20231013083839411
1
sed -n 'N;P' students.db 	#打印奇数行

image-20231013083908986

sed空间

sed同时维护两个内存缓冲区
• 模式空间(pattern space)
• 保持空间(hold space),也译为暂存空间

模式空间
• 不断从输入获取新行
• 可通过sed脚本修改其内容
• 每次执行完sed脚本后会被清空(有些命令如D除外)

暂存空间
• 只能从模式空间获得内容
• 其内容既不能直接修改也不会自动被清空
• 其内容需导入模式空间后才能被修改

1
2
3
4
5
6
7
8
9
10
x – exchange
• 交换模式空间和保持空间的内容。
• h – hold pattern space
• 保存模式空间的内容至保持空间 (覆盖)
• H – Hold pattern space
• 保存模式空间的内容至保持空间尾部 (用换行符分隔)
• g – get contents of hold area
• 获取保持空间的内容到模式空间 (覆盖)
• G – Get contents of hold area
• 获取保持空间的内容至模式空间尾部 (用换行符分隔)
sed流程控制

• 标签

1
: label #为跳转语句设置跳转标签label

分支(branch)跳转

1
2
b label #跳转到标签label位置
b #跳转到脚本结束位置

测试(test)跳转

1
2
3
t label #仅当读取最新输入行(或执行条件跳转)之后成功执行了
s命令,才跳转到标签label位置
t #同上,但跳转到脚本结束位置

awk

awk 是一种强大的文本处理工具,通常用于从文件或者输入流中抽取和处理数据。它是一种类似于编程语言的工具,用于按照指定的规则处理文本行。

基本用法
1
awk 'pattern { action }' filename
  • pattern: 模式,用于匹配文本行。
  • action: 在匹配模式的情况下执行的操作。
示例
  1. 显示文件的第一列:

    1
    awk '{print $1}' filename.txt
  2. 计算文件的总行数:

    1
    awk 'END {print NR}' filename.txt
  3. 计算文件的总和:

    1
    awk '{sum += $2} END {print "Sum:", sum}' filename.txt
  4. 查找并打印包含特定文本的行:

    1
    awk '/pattern/ {print}' filename.txt
  5. 显示文件中每行的字符数:

    1
    awk '{print length($0)}' filename.txt
  6. 过滤并打印满足条件的行:

    1
    awk '$3 > 50 {print}' filename.txt
  7. 在列中查找最大值:

    1
    awk 'max < $2 {max = $2} END {print "Max value:", max}' filename.txt
  8. 计算平均值并显示小数:

    1
    awk '{sum += $3} END {print "Average:", sum/NR}' filename.txt
  9. 删除空白行:

    1
    awk NF filename.txt
  10. 在特定列中查找并替换值:

    1
    awk '$4 == "old_value" {$4 = "new_value"} {print}' filename.txt
  11. 逐行执行多个操作:

    1
    awk '{if ($2 > 50) {print $1 " Pass"} else {print $1 " Fail"}}' scores.txt
  12. 按列合并两个文件:

    1
    awk 'NR==FNR{a[$1]=$2; next} {print $0, a[$1]}' file1.txt file2.txt
  13. 在两个文件中查找并显示匹配行:

    1
    awk 'NR==FNR{a[$1]=$0; next} $1 in a {print a[$1], $0}' file1.txt file2.txt

用户组和权限管理

用户账户

用户帐号代表用户身份,具有唯一的UID

根账户(root)

• 超级用户root可以不受限制地执行所有任务
• UID:0
• 主目录:/root

系统账户

• 系统或应用程序使用的账户,供服务使用的也称服务账户
• UID:1-999、65534
• 主目录:各有不同

普通账户

• 供实际普通用户登录使用的账户
• UID:从1000开始顺序编号
• 主目录:/home/username
• 普通用户默认无法访问其他用户的主目录

用户配置文件

用户账户配置文件

/etc/passwd
  • 存放除密码之外的账户信息
  • 所有用户均可读取
  • 记录格式:man 5 passwd
  • 用户密码配置文件
/etc/shadow
  • 存放与用户密码相关的信息
  • CentOS 7默认使用sha512哈希算法加密用户口令
  • 除root外,所有用户均无法读取
  • 记录格式:man 5 shadow

组账户

组是用户的集合,具有唯一GID。可以以组为单位分配权限,则组内成员自动获得所分配权限

  • 一个用户可以同时属于多个组

    一个主要组(Primary Group),也叫初始组(InitialGroup),即用户的默认组,创建用户时默认会自动创建一个与用户同名的组作为其主要组(默认组)
    若干次要组
    用户可以在不同组身份之间进行切换

  • Linux不支持嵌套组

    组成员只能是用户,不能是其他组

组的类别

超级组(Superuser Group)

• 组名:root
• GID:0
• 不像root用户一样具有超级权限

系统组(System Group)

• 由系统或应用程序使用
• GID:1-999、65534

自定义组

• 由管理员创建
• GID:默认从1000开始顺序编号
• 私有组:创建用户时自动创建的同名自定义组
• 标准组:私有组之外的自定义组

组配置文件

组账户配置文件

/etc/group
  • 存放除密码之外的组账户信息
  • 所有用户均可读取
  • 记录格式:man 5 group

组密码配置文件

/etc/gshadow
  • 存放与组密码相关的信息
  • 除root外,所有用户均无法读取
  • 记录格式:man 5 gshadow

验证账号文件的一致性

不建议直接编辑修改系统账户文件,直接编辑账户文件后建议检测账号文件的一致性

pwck

检测/etc/passwd和/etc/shadow的字段格式和值

grpck

检测/etc/group和/etc/gshadow的字段格式和值

useradd 添加用户

  • -g 指定新用户的主(私有)组
  • -G 指定新用户的附加组
  • -d 指定新用户的主目录
  • -s 指定新用户使用的Shell,默认为bash
  • -e 指定用户的登录失效时间,如08/10/2001

passwd 修改密码

passwd

让用户免密码进行本地登录的两种方法:

  • 将/etc/passwd 文件中的密码字段清空
  • 将/etc/shadow 文件中的密码字段清空

远程用户必须设置了登录密码才允许登录!

id 查询用户信息

usermod 修改用户账户

userdel 删除用户

groupadd 添加组

gpasswd 设置组密码

groupmod 修改组

groupdel 删除组

groups 查询组信息

用户权限

chmod

更改权限

仅文件所有者和 root 用户有权修改文件权限

1
2
3
4
5
6
7
$ chmod u=rw-,g=r--,o=r-- file # 字符绝对设置法
$ chmod g+w,o-r file # 字符相对设置法
$ chmod a+x file
$ chmod 644 file # 八进制设置法
$ chmod 600 file
$ chmod 700 dir
$ chmod -R 755 dir # 递归设置权限
chown

改变文件的所有者和属组

• 只有root用户才能改变文件的所有者

• 只有root用户或所有者才能改变文件所属的组 (所有者必须是该组成员)

1
2
3
4
5
6
7
8
# chown root file # 设置file为root所有
# chown root:users file # 设置file为root所有,属users组
# chown root: file # 设置file为root所有,属root组
# chown :users file # 设置file属users组
# chown -R root:users dir # 递归处理

# chgrp users file # 设置file属users组
# chgrp -R users dir # 递归处理

进程与作业管理

进程

  • 进程由程序产生,是动态的概念,代表一个运行着的、 要占用系统运行资源的程序。

  • 内核通过进程控制块(Process Control Block, PCB) 来管理每个进程,每个PCB都具有一个唯一的进程标 识符,即PID。

父进程与子进程

一个进程启动另一个进程,就成为父进程,被启动的 进程就是该父进程的子进程

1
2
3
$ pstree 	# 打印进程树
$ pstree -c # 打印时不合并重复子树
$ pstree -p # 打印时显示进程PID

ps 查看进程

ps (process status):显示进程列表及其状态

1
2
3
$ ps # 查看当前 shell 执行的进程
$ ps aux # 查看所有进程 (BSD 风格)
$ ps -ef # 查看所有进程 (System V 风格)

搜索进程

1
2
$ ps aux | grep sshd 	# 搜索sshd进程
$ ps -C sshd -o pid # 打印sshd进程的pid列

top 查看动态的进程信息

nohup 后台运行进程

  • 通常当用户注销后,所有属于该用户的进程将全 部被终止(SIGHUP)
  • 如果希望程序在退出系统后仍然能够继续运行, 可以使用 nohup 命令启动该进程。
  • nohup 命令 [选项] [参数] [输出文件] &
1
2
3
4
5
6
7
$ nohup ping www.baidu.com &
# 若程序有结果输出,输出结果将会被保存到当前目录下的一个文件名
为 nohup.out 的文件中
# 若用户在当前目录没有写的权限,则结果将会被保存到用户主目录下
的 nohup.out 文件中
# 也可以用输出重定向指定结果保存位置
$ nohup ping www.baidu.com >ping.out 2>/dev/null &

lsof 查看进程打开的文件

lsof:list open files

1
2
3
4
5
# lsof /dev/pts/0 # 由文件名查找进程
# lsof -d 0 # 由文件描述符查找进程
# lsof -p 1234 # 由PID查找打开的文件
# lsof -u tom # 查看某一用户打开的文件
# lsof -i:22 # 由端口号查找进程

shell脚本编程

执行shell脚本

1
2
3
4
sh <script.sh
sh script.sh
. script.sh
source script.sh

与位置参数有关的变量

1
2
3
4
5
6
$0 					# 当前脚本路径名
$1, $2, ..., $9 # 位置参数
${10} # 第 10 个位置参数
$* # 所有位置参数(不包括$0)
$@ # 所有位置参数(不包括$0)
$# # 位置参数个数(不包括$0)

shift

shift [n]:所有位置参数左移n位(默认左移1位)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ cat shiftarg
echo "arg counts: $#"
echo "args: $@"
echo "first arg: $1"
shift
echo "shift"
echo "arg counts: $#"
echo "args: $@"
echo "first arg: $1"
shift 3
echo "shift 3"
echo "arg counts: $#"
echo "args: $@"
echo "first arg: $1"
$ shiftarg 1 2 3 4 5 6 7 8 9

由于一共使用shift将位置参数左移4位,所以最后只剩5 6 7 8 9参数了

变量

1
x=100 		# 变量无需声明,=两边不能加空格!

shell中的变量默认是字符串

unset 删除变量
1
2
unset x; 
echo $x

此时x变量是没有定义的、没有值

decalre 声明变量
1
2
3
declare -i y; echo $y 		# 声明变量为整型变量
declare -r y; y=123 # 声明变量为只读变量
declare -p y # 显示变量声明及其值

特殊变量

1
2
3
4
5
$? 		# 上一条命令的退出码
$- # bash选项,查看help set了解选项含义
$$ # 当前进程的PID
$! # 上一个后台进程的PID
$_ # 上一条命令的最后一个参数(详细参看man bash)

命令替换

$(),在这里面可以执行命令,或者使用反引号**`**也可以进行命令替换

1
2
3
4
$ date='04/10/2020'
$ echo ${date} # 变量替换,这里会输出date变量的值
$ echo $(date) # 命令替换,这里会输出date命令运行后的结果
$ echo `date` # 命令替换,这里会输出date命令运行后的结果

变量替换

在双引号""中,可以使用${}的形式来在字符串中替换变量的值(使用{}括起来可以精确表示变量的开始范围)

1
2
3
4
5
$ a=teach
$ echo $a
$ echo "he is a $aer" # 此时输出 he is a 与后面的er混淆了,没有$aer变量
$ echo "he is a ${a}er" # 此时输出 he is a teacher
$ echo 'he is a ${a}er' # 单引号不能替换
条件变量替换

以下变量替换中如果包含冒号”:”,则检查变量是否 存在或其值是否为null,如果不包含冒号,则仅检查 变量是否存在。

1
2
3
4
5
6
7
8
9
${a:-b} 使用默认值
若a存在且非空,则返回a的值,否则返回b的值
${a:=b} 赋值为默认值
若a存在且非空,则返回a的值,否则将a赋值为b并返回a的新值
${a:?b} 报告错误
若a存在且非空,则返回a的值,否则将b写入标准错误(对于非交互式
shell则直接退出shell)
${a:+b} 使用替换值
若a存在且非空,则返回b的值,否则返回空
截断变量替换

以下变量替换并未改变变量本身的值

1
2
3
4
5
6
7
8
${a%b}
从a值的右端去掉与b值的最短匹配,返回剩下的部分
${a%%b}
从a值的右端去掉与b值的最长匹配,返回剩下的部分
${a#b}
从a值的左端去掉与b值的最短匹配,返回剩下的部分
${a##b}
从a值的左端去掉与b值的最长匹配,返回剩下的部分
获取变量长度

在变量前面加个#可以计算变量长度 `$


Linux操作系统笔记
https://leekosss.github.io/2023/10/01/Linux操作系统笔记/
作者
leekos
发布于
2023年10月1日
更新于
2023年12月29日
许可协议