Linux [ Shell [ Bash ]]

"learning……"

Posted by Ryan on December 15, 2024

枪响了,他没有死去,子弹在头骨上开了个指头大小的脑洞。他疑惑地把手指插进,发现伤口融化成回忆,酸楚涌入脑浆。子弹打通了堵塞的思绪,透过弹孔回忆起她的故事…

复习一下实习时用过的Linux命令,然后温故而后知新~

Linux 基础

Linux系统的默认命令行接口是shell(一般为bash),通过在终端中输入命令来执行各种操作。shell提供了丰富的命令和参数,可以操作文件、目录、进程等。

文件系统

  1. 文件操作:
    • touch命令:创建空文件或修改文件的时间戳。
    • cp命令:复制文件或目录。
    • mv命令:移动文件或目录,也可以用于修改文件名。
    • rm命令:删除文件或目录。
    • cat命令:显示文件内容。
    • less命令:逐页显示文件内容。
    • head命令:显示文件的前几行。
    • tail命令:显示文件的后几行。
    • stat命令:查看文件inode信息。
  2. 目录操作:
    • cd命令:切换当前工作目录。
    • pwd命令:显示当前所在的目录。
    • ls命令:列出当前目录下的文件和子目录。
    • mkdir命令:创建目录。
    • rmdir命令:删除空目录。
    • tree命令:以树状结构显示目录及其子目录。
  3. 系统管理:
    • ps命令:列出当前正在运行的进程。
    • top命令:实时显示系统资源使用情况。
    • df命令:查看磁盘空间使用情况。
    • du命令:查看指定目录或文件的磁盘空间使用情况。
    • uname命令:显示系统信息。
    • ifconfig命令:显示网络接口信息。
    • ping命令:检测网络连通性。
  4. 网络通信:
    • ssh命令:远程登录到其他Linux主机。
    • scp命令:在本地和远程主机之间传输文件。
    • ftp命令:使用FTP协议与远程主机交互。
    • telnet命令:使用Telnet协议连接到远程主机。
    • curl命令:从命令行发送HTTP请求。

Linux 命令中的符号

  1. 单引号内的内容是强引用,都会被认为是字符,对变量输出而言双引号和不带引号效果一样
  2. 反斜杠是续行符,比如$ echo \n ,只输出n
  3. 双感叹号!!,会输出上一个命令
  4. 感叹号加字符描述,会输出以字符开头的第一个命令

Linux 命令中的快捷键

  1. 输入clear可以清屏
  2. 输入pwd可以输出当前所在位置(目录)
  3. 上下键可以搜索命令
  4. ctrl+e光标移到行尾
  5. ctrl+a光标移到行首
  6. ctrl+w删除光标前的一个单词
  7. ctrl+u删除光标前的内容
  8. ctrl+k删除光标后的内容
  9. ctrl+y将刚刚删除的内容返还回来
  10. ctrl+l清屏
  11. tab补全
  12. 双击tab显示可补全的内容

echo 回声

1
2
3
4
5
6
7
$ echo                //echo后什么都不跟,默认打印出一个空行
$ echo hello          //echo后跟字符串,会打印出字符串并且跟一个字符串
$ echo -n hello       //只打印字符串,不打印换行
$ echo $?             //打印上一个命令是否运行成功,成功的话打印0
$ name=xx
$ echo $name          //打印变量的值,会输出xx
$ echo -e "字符"      //-e命令使得echo输出的双引号内容可以包含转义字符

cd 切换目录

1
2
3
4
5
$ cd 目录             //直接切换到对应地址的目录
$ cd ..               //返回上一级目录
$ cd ~                //返回home目录
$ cd /                //返回根目录
$ cd -                //返回上一个访问目录

find 查找目录/文件

1
2
3
4
5
6
$ find . -name "test1.txt"        //查找 目录(.) 以文件名查找(-name) 文件名
$ find . -name "*.txt"            //查找 目录(.) 以文件名查找(-name) 文件类型
$ find . -iname "*.txt"           //查找 目录(.) 以文件名查找且忽略大小写(-iname) 文件类型
$ find . -type f                  //查找 目录(.) 以文件类型查找 file文件类型
$ find . -type d                  //查找 目录(.) 以文件类型查找 directory目录类型
$ find . -type l                  //查找 目录(.) 以文件类型查找 symbolic link符号链接

mkdir 创建文件夹目录

1
2
3
$ mkdir test1                     //在当前目录下创建一个文件夹目录
$ mkdir test2 test3               //在当前目录下同时创建多个文件夹目录
$ mkdir -p test4/subdir1          //在当前目录下同时创建多级文件夹目录

cp 复制命令

1
2
3
4
$ cp test.txt test1.txt           //在当前目录下复制源文件成目标文件
$ cp -r testdir testdir2          //在当前目录下复制源目录成目标目录
$ cp -v test.txt testdir          //在当前目录下复制源文件到目标目录下
$ cp -i test.txt test.txt         //询问是否覆盖

cat 查看文件内容命令

1
2
3
4
5
$ cat testfile1.txt               //查看文件所有内容
$ cat -n testfile1.txt            //显示行号
$ cat -s testfile1.txt            //不打印空行
$ cat -E testfile1.txt            //$标志行开始
$ cat -T testfile1.txt            //将tab键变成^输出

rm 删除命令

1
2
3
$ rm testfile.txt                 //删除文件
$ rm -r test1                     //删除目录
$ rm -i -r test1                  //删除目录,并且询问是否删除

wc 计数命令

1
2
3
4
5
$ wc testfile.txt                 //打印文本中的行数 单词数 字节数
$ wc -l testfile.txt              //单独打印文本中的行数
$ wc -w testfile.txt              //单独打印文本中的单词数
$ wc -c testfile.txt              //单独打印文本中的字节数
$ wc -m testfile.txt              //单独打印文本中的字符数

tar 压缩和解压

1
2
3
$ tar -cf testdir.tar testdir     //压缩
$ tar -zcf testdir.tar.gz testdir //压缩成tar.gz
$ tar -xf testdir.tar             //解缩

tail 查看文件尾

跟踪log

1
2
3
$ tail testfile1.txt              //查看文件倒数十行内容
$ tail -n 5 testfile1.txt         //查看文件倒数五行内容
$ tail -f test.log                //跟踪log

vi 文本编辑器

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
$ vi test.txt 创建txt并进入
i 在当前字符前插入文本
I 在行首插入文本
a 在当前字符后添加文本
A 在行末添加文本
o 在当前行后面插入一空行
O 在当前行前面插入一空行
^ 行首,第一个不是空白字符的位置
$ 行尾
gg 文件顶部
G 文件末尾
数字gg 移动到 数字 对应行数
数字G 移动到 数字 对应行数
u 撤销上次命令
U 撤销当前用户的所有的编辑操作
Ctrl+r 恢复撤销的命令
Ctrl+b 向上翻页
Ctrl+f 向下翻页
Ctrl+g 显示光标所在位置的行号和文件的总行数
v 从光标位置开始按照正常模式选择文本
V 选中光标经过的完整行
x 删除光标所在字符,或者选中文字
dd 删除光标所在行,可以 ndd 删除多行
D 删除至行尾
yy 复制一行,可以 nyy 复制多行
p 粘贴
/str 查找 str
n 查找下一个(必须在查找状态下执行)
N 查找上一个(必须在查找状态下执行)
gUU 将当前行的字母全改成大写
guu 将当前行的字母全改成小写
gUw 将光标下的单词改成大写
guw 将光标下的单词改成小写
g~~ 行翻转(大小写互换)
ZZ 保存并退出
ZQ 不保存并退出# 末行模式(:):
:数字 移动到 数字 对应行数
:%d 删除全部
:%s/旧文本/新文本/g 查找并替换
:%s/旧文本/新文本/gc 查找并替换,会有提示(y-替换;n-不替换;q-退出替换;l-最后一个,并把光标移动到行首)
:r 文件的路径及文件名 在当前文件中读入其他文件的内容
:r! 命令名 将某一命令的结果追加到当前行的下一行
:w 保存
:w 文件的路径及文件名 另存为其他文件
:q 退出,如果没有保存,不允许退出
:w! 强行保存
:q! 强行退出,不保存退出
:wq 保存并退出
:wq! 强制保存并退出
:x 保存并退出
:set nu 显示行号
:set nonnu 取消行号
:history 列出历史命令记录
:pwd 显示当前所在的路径

grep 命令

1
2
3
4
5
$ grep -i hello testfile1.txt            //匹配所有包含hello的文本并输出
$ grep -w hello testfile1.txt            //严格匹配hello的文本并输出
$ grep -n hello testfile1.txt            //匹配所有包含hello的文本并输出并显示行号
$ grep -e hello -e today testfile1.txt   //匹配多个文本并输出并显示行号
$ grep -r hello testdir/                 //递归查找目录下包含hello的文件

正则表达式:
image

管道符

将前一个命令的标准输出作为后一个命令的输入,标准错误输出不能传递

1
$ cat file.txt | grep "error"

输出重定向符

1
2
3
4
5
6
7
8
9
10
11
12
$ command > file                    //覆盖写入
$ echo "Hello, World!" > output.txt
$ command >> file                   //追加写入
$ echo "Another line" >> output.txt
$ command 2> file                   //重定向标准错误输出,将错误信息输出到log
$ ls nonexistentfile 2> error.log
$ command 2>> file                  //追加写入标准错误输出
$ ls nonexistentfile 2>> error.log
$ command &> file                   //将标准输出(stdout)和标准错误(stderr)同时重定向到同一个文件,会覆盖内容
$ command &> all_output.log
$ command &>> file                  //将标准输出(stdout)和标准错误(stderr)同时追加到指定文件
$ command > stdout.log 2> stderr.log//可以分别处理标准输出和错误输出。

输入重定向符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ command < file                    
$ cat < input.txt                   //将 input.txt 的内容作为输入提供给 cat 命令(功能等同于 cat input.txt)。
$ command << EOF                    //将多行内容作为输入,通过在命令后定义一个结束标记来结束输入。
>data_line1
>data_line2
>EOF
$ command <<< "string"
$ grep "hello" <<< "hello world"    //将 "hello world" 字符串作为输入传递给 grep 命令
$ sort < data.txt                   //将 data.txt 文件内容作为输入,排序后输出到终端
    
$ wc -w << EOF                      //将多行内容提供给 wc -w 命令,计算单词数
>This is line 1
>This is line 2
>EOF

$ bc <<< "5 + 10"                   //将 5 + 10 作为输入传递给 bc(计算器),输出结果为 15
$ cat < input.txt | grep "keyword"  //从 input.txt 读取内容,通过管道传递给 grep 命令筛选包含 keyword 的行

printf 命令

主要用于对其格式的输出

1
2
3
4
5
6
7
8
9
10
11
12
$ printf FORMAT [ARGUMENT]...
$ printf "hello,world!\n"            //printf 不会自动换行,需显式指定
$ printf "Number:%d\n" 42            //%d 用于格式化整数,输出 Number: 42
% printf "Float: %.2f\n" 3.14159     //%.2f 用于格式化浮点数,保留两位小数,输出 Float: 3.14

% name="John"                        //输出 John is 30 years old.
% age=30
% printf "%s is %d years old.\n" "$name" "$age"

% printf "%10s\n" "Hi"               //Hi(前面有 8 个空格)
% printf "%-10s\n" "Hi"              //左对齐,Hi (后面有 8 个空格)
% printf "%010d\n" 123               //0000000123

touch 命令

主要用于更新文件时间
Linux文件有三种时间戳:

  1. 访问时间(atime):文件最后被读取的时间
  2. 修改时间(mtime):文件内容最后被修改的时间
  3. 状态改变时间(ctime):文件元数据(如权限、所有权等)最后被更改的时间
1
2
3
4
5
$ touch file1                        //如果文件不存在会自己创建一个
$ touch file1 file2 file3            //同时创建 file1、file2 和 file3
$ touch existing_file                //touch一个已经存在的文件,会更新文件的时间
$ touch -t 202412151200 file1        //touch指定文件时间
$ touch -c file1                     //如果 file1 不存在,不会创建它,仅尝试更新文件时间

image

xargs 命令

  1. 将标准输入传递给命令作为参数
  2. 处理输入数据过多的问题,避免命令参数过长
  3. 组合命令,方便批量操作
1
2
3
4
$ echo "file1 file2 file3" | xargs rm        //将字符串 file1 file2 file3 传递给 rm 命令
$ find /path/to/files -type f -name "*.log" | xargs rm -f  //查找并删除 /path/to/files 目录下所有 .log 文件
$ ls | xargs -I {} mv {} /new/path           //将当前目录中的所有文件移动到 /new/path
$ echo "dir1 dir2 dir3" | xargs -n 1 mkdir   //批量创建 dir1、dir2 和 dir3 三个目录

ls 命令

image

1
2
3
4
5
6
7
$ ls                        //显示当前目录中的文件和子目录名称
$ ls -a                     //显示包括隐藏文件(以 . 开头的文件)在内的所有文件
$ ls -A                     //显示包括隐藏文件(以 . 开头的文件)在内的所有文件,不包含.和..
$ ls -l                     //以长格式显示文件详细信息
$ ls -lt                    //按修改时间排序
$ ls -ld /path/to/dir       //显示目录自身
$ ll                        //ls -l的缩写

inode与硬链接和软连接

inode是Linux文件系统的核心,在 Linux 和 Unix 文件系统中,inode(索引节点)是一种数据结构,用于存储有关文件或目录的元信息(metadata)。每个文件和目录在文件系统中都有一个唯一的 inode 编号,它是文件系统中管理和检索文件的重要机制。源信息包括:文件字节数、拥有者ID、Group ID、文件权限、时间戳(atime、mtime、ctime)、链接数、文件数据block所在位置。

1
2
3
$ stat example.txt            //stat命令查看文件信息
$ ls -i 文件名                //查看一个文件的inode编号
$ find . -inum <inode_number> -exec rm -i {} \  //如果文件名包含特殊字符(如 - 或空格),可以直接通过 inode 删除

工作原理:

  1. 文件创建
    • 当在文件系统中创建一个新文件时,系统会分配一个空闲的 inode 和相应的数据块。
    • 文件名和 inode 编号通过目录结构关联。
  2. 文件访问
    • 当访问文件时,操作系统根据文件名找到对应的 inode 编号。
    • 再通过 inode 中的指针,找到存储文件内容的数据块。

inode特点:

  1. inode编号唯一性:
    • 每个文件和目录在文件系统中都有唯一的 inode 编号,但它只在特定文件系统范围内唯一。
  2. 硬链接与inode:
    • 硬链接指向相同的 inode,因此它们共享文件内容和元信息。
    • 删除一个硬链接不会删除文件内容,只有当指向同一个 inode 的所有硬链接都被删除时,文件内容才会从磁盘上移除。
  3. inode表:
    • 文件系统会维护一个 inode 表(相当于 inode 的集合),记录所有文件的 inode 信息。

inode应用:

  1. 硬链接与符号链接(软连接)
    • 硬链接指向相同的inode,文件共享inode和数据块
    • 只有当所有的硬链接全被删除时,文件才会被真正删除(这点像shared_ptr)
    • 符号链接是一个独立文件,存储了目标文件路径,与目标文件inode无关
  2. 磁盘空间不足VS inode耗尽
    • 如果磁盘已满,无法创建新文件(数据块耗尽)
    • 如果inode耗尽,即使还有磁盘空间也无法创建新文件

image

ln 命令

ln能创建链接,其中硬链接只能给文件创建,软链接可以给文件和目录创建。硬链接(Hard Link)是一种文件系统中的文件引用机制,它允许多个文件名指向同一个 inode(即文件内容的存储位置)。硬链接与原始文件共享相同的文件内容和元数据,删除一个硬链接不会影响其他硬链接的内容。硬链接不存储文件名,而是直接与文件的 inode 关联,因此文件内容只有在所有指向该 inode 的硬链接都被删除时,才会从磁盘中移除。软链接(Symbolic Link,简称 symlink)是 Linux 和 Unix 系统中一种特殊的文件,它是指向另一个文件或目录的路径的链接。与硬链接不同,软链接是独立的文件,它包含目标文件或目录的路径信息,类似于 Windows 中的快捷方式。软链接可以跨文件系统,且可以指向目录。

1
2
3
$ ln <源文件> <硬链接>                  //为源文件创建一个硬链接,文件目录是不能有硬连接的
$ ln -s <目标文件或目录> <软链接文件名> //为源文件或者目录创建一个软链接
$ rm <链接名>                          //删除一个链接

mv 命令

1
2
3
4
5
6
7
$ mv old_name.txt new_name.txt          //mv命令用来修改文件名
$ mv file1.txt /path/to/destination/    //移动到另一个位置
$ mv file1.txt file2.txt file3.txt /path/to/destination/        //移动多个文件
$ mv old_dir new_dir                    //目录改名
$ mv -i file1.txt /path/to/destination/ //覆盖文件之前提示确认interactive
$ mv -f file1.txt /path/to/destination/ //强制移动force
$ mv -v file1.txt /path/to/destination/ //-v(verbose)显示详细的移动过程,列出每个文件的移动情况。

alias

给很长的命令取别名,这样可以简化使用

1
$ alias cp='cp -i'

cut

tr

sort

unique

watch

权限管理

Linux 文件权限

看以下这个文件目录的头部,其中d代表directory文件夹类型,d后面跟着的前三个rwx代表当前用户(user)的权限为读写执行,中间三个rwx代表和你同组(group)的人的权限为读写执行,最后三个r-x代表其他组(others)的权限为读执行

1
drwxrwxr-x 2 test test  6 Dec 15 22:46 test1

useradd 命令

1
2
3
4
5
6
7
$ useradd user1                //新增一个用户名
$ useradd -p 123456 user1      //创建用户并指定密码
$ passwd user1                 //修改user1的密码或者初始化密码
$ useradd -g groupname username    //加入组
$ useradd -G group1,group2 username//加入多个组
$ useradd -u 1001 username//指定用户ID
$ useradd -e YYYY-MM-DD username   //指定密码有效期

image

usermod

1
2
3
$ usermod -c "描述信息"        //添加描述信息
$ usermod -g groupname username//换组
$ usermod -l newname oldname   //改名

userdel 删除命令

1
2
$ userdel username             //删除用户账户,但不删除邮件和家目录
$ userdel -r username          //删除用户账户,且删除所有文件

group 组

1
2
3
4
$ groupadd groupname           //新增组
$ groupadd -g 1010 groupname   //新增组,指定组ID
$ groupdel groupname           //删除组
$ groupmod -g 1111 newgrouname //修改组名和组ID

chown

更改文件或目录的所有者和/或所属组

1
2
3
4
$ chown username file            //将文件 file 的所有者更改为 username
$ chown :groupname file          //将文件 file 的所属组更改为 groupname
$ chown -R username:groupname directory/        //递归更改目录及其内容的所有者和组
$ chown 1001:1002 file           //修改文件所有者UID和所属组GID

image

chmod

image image

1
2
3
4
5
$ chmod u+rw fliename             //用户增加对本文件的读写权限
$ chmod u+rw dir                  //用户增加对本目录的读写权限
$ chmod g-rw fliename             //组解除对本文件的读写权限
$ chmod 777 filename              //数字表示法
$ chmod 777 -R dir                //递归改权限

su 切换用户

root用户切换任意用户都不需要密码,普通用户切换root用户或者普通用户之间互相切换,需要密码

1
$ su user1                        //切换

sudo 超级用户

sudo权限更高,在命令前加sudo以获取权限,但是使用sudo需要密码和root用户配置权限。

hostname

1
2
$ hostname                        //显示主机名
$ hostname vm1                    //临时修改主机名

top实时监控

top打印出实时监控窗口后,按h可以查看所有交互功能