Linux常用命令

Shell

前言:启动某个程序:查找程序在硬盘上安装位置,然后将其加载到内存运行。真正能控制硬件(CPU,显示器,内存)的只有OS kernel。但由于安全,复杂等原因用户不能直接接触内核,则在user与kernel增加一层“代理”(UI与命令行程序)。来接收用户操作,简单处理后传给 kernel。

  1. Shell是一个命令行程序,连接user与Linux kernel,让user更高效用Linux kernel。运行一个命令,大部分情况下Shell都会调用内核暴露出来的接口。这就是在使用内核。
  2. Shell也支持编程。Shell也是一种脚本语言(Script),解释型语言的别称是脚本语言(Script)。

Linux版本

  1. 核心版本
  2. 发行版本

Shell与Bash

  • Shell

Shell 是用户与操作系统内核之间的接口,允许用户通过输入命令与系统交互。它可以是命令行界面(CLI)或图形用户界面(GUI),但通常指 CLI。Shell 接收用户输入的命令,解释并执行它们。

  • Bash

Bash(Bourne Again Shell)是 Shell 的一种,由 Brian Fox 为 GNU 项目开发。它基于 Bourne Shell(sh),增加了更多功能,如命令行编辑、命令历史、脚本编程等。Bash 是许多 Linux 发行版的默认 Shell。

区别

  • 定义:

Shell 是用户与操作系统交互的接口。

Bash 是 Shell 的一种实现。

  • 功能:

Shell 提供基本的命令解释和执行功能。

Bash 在 Shell 的基础上增加了更多高级功能,如命令行编辑、命令历史等。

  • 兼容性:

Shell 通常指 Bourne Shell(sh)。

Bash 兼容 sh,并扩展了更多功能。

  • 使用场景:

Shell 适用于基本的命令行操作。

Bash 更适合复杂的脚本编写和交互式使用。

Shell命令与Bash命令

  1. Shell 命令

Shell 命令 是指通过 Shell(命令行解释器)执行的命令。

Shell 是一个统称,包括多种不同的 Shell 实现,比如:

1
2
3
4
5
6
7
8
9
Bash(Bourne Again Shell)

sh(Bourne Shell)

zsh(Z Shell)

csh(C Shell)

fish(Friendly Interactive Shell)

无论你使用哪种 Shell,都可以执行一些基本的命令,比如 ls、cd、echo 等。这些命令是 Shell 通用的。

  1. Bash 命令

Bash 命令 是特指在 Bash Shell 中执行的命令。
Bash 是 Shell 的一种,因此 Bash 命令也是 Shell 命令的一部分。
Bash 支持一些额外的功能和语法,比如:

  • 命令行编辑(使用方向键修改命令)
  • 命令历史(通过 history 查看)
  • 更强大的脚本编程功能(如数组、条件判断、循环等):例如,${VAR:-default} 这种语法是 Bash 特有的,其他 Shell 可能不支持。
  1. 为什么容易混淆?

因为 Bash 是目前最常用的 Shell,很多人默认使用的就是 Bash,所以经常把“Shell 命令”和“Bash 命令”混为一谈。
如果你在 Linux 或 macOS 的终端中输入命令,大概率是在 Bash 中运行的,所以你会觉得“Shell 命令”和“Bash 命令”是一回事。

  1. 如何区分?

如果你在写脚本或执行命令时,使用的是 Bash 特有的功能(比如 [[ ]] 条件判断、${VAR} 变量扩展等),那么这些就是 Bash 命令。
如果你使用的是非常基础的命令(比如 ls、cd、echo),这些是 Shell 命令,几乎所有的 Shell 都支持。

  1. 总结

Shell 命令 是通用的,适用于所有 Shell。

Bash 命令 是 Shell 命令的一部分,特指 Bash 支持的命令和语法。

如果你不确定自己用的是哪种 Shell,可以运行以下命令查看:

1
$ echo $SHELL #如果显示 /bin/bash,说明你正在使用 Bash。

Shell界面

Linux系统提供的命令需要在shell环境下运行,需要从图形界面进入shell界面,即终端(konsole)

命令格式

  • bash命令的一般格式:命令名+选项+参数
  • 正常执行后返回0,否则返回非零值(通过命令$?)查看
  • 一行放不下,用反斜杠\来中继
  • 连续的空格会被解释为单个空格

简单命令

  1. who命令:显示用户名+终端名+注册时间
  2. echo命令:
1
2
3
4
5
$ echo i am chy

$ echo i am a good boy #多个空格按一格

$ echo 'i am a good boy'
  1. date命令:显示日期
  2. cal命令:显示日历
1
2
3
4
5
6
7
$ cal #显示当前月份

$ cal 10 #显示公元10年的月份

$ cal 2 2025 #不言而喻

$ cal Feb 2025 #更洋气
  1. clear命令:清屏
  2. passwd命令:修改密码

文件系统

  1. .是当前目录;..是当前目录的父目录;使用cd可以切换到家目录;最上层的目录称为根目录(root),用/表示。
  2. .开头的是隐藏文件;以-开头的是普通文件;以d开头的是目录文件;以l开头的是符号链接文件。
  3. Linux的四种文件类型
    • 普通文件
    • 目录文件
    • 设备文件(访问硬件的驱动程序(Linux 内核的一部分)的接口)
    • 符号链接文件

文件操作命令

文件显示命令

  1. cat命令:显示文件、连接两个或多个文件
1
2
3
4
5
$ cat f1 #显示f1内容

$ cat f1 f2 #同时显示f1与f2内容

$ cat f1 f2 > f3 #把文件f1与f2中的内容合并放到f3中,如果 f3 原本有内容,执行该命令后会被完全替换,且无法恢复。使用>>追# 加,terminal不会显示任何事物

404

  1. more命令:每次显示一屏
1
2
3
$ more -dc f1 #-d 显示友好信息    -c 先清屏

$ more -c -10 f1 #每10行显示一次,显示前先清屏
  • space:显示下一屏
  • enter:显示下一行
  • B:上一屏
  • Q:退出
  1. less命令:同more命令
    增强处在于:
  • 使用切换行
  1. head命令:显示文件开头若干行(默认10)
1
$ head -5 f1 # 显示5行
  1. tail命令:显示末尾若干行(默认10)
1
2
3
4
5
6
$ tail +20 f1 # 从文件20行显示到最后

$ tail -c 10 f1 # 显示f1最后10个字符

$ tail -f f1 #The -f flag makes tail keep the file open and continuously print new lines as they are appended.
# To exit, press Ctrl+C
  1. touch命令:修改指定文件时间标签或者创建一个空文件
1
$ touch f1 # 创建文件f1

404

匹配、排序、显示指定内容的命令

  1. grep命令:查找指定的词或者短语
1
2
3
4
5
6
7
$ grep -F hello f1 # 在f1中查找hello所在的‘行’。-F表明此时hello为单纯字符串

$ grep -r 'print' d1 # 以递归方式查询目录d1子目录下的所有文件

$ grep -E '[Mm]i || [Yy]j' f1 f2 # 此时字符串为正则表达式 Expression

$ grep -i 'main' f1 # 比较时不区分大小写
  1. sort命令:排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
sort testfile 

# sort 命令将以默认的方式将文本文件的第一列以 ASCII 码的次序排列,并将结果输出到标准输出。
$ cat testfile # testfile文件原有排序
test 30
Hello 95
Linux 85

$ sort testfile # 重排结果
Hello 95
Linux 85
test 30

$ sort testfile -k 2
test 30
Linux 85
Hello 95

  1. uniq命令:去重
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
uniq testfile 

$ cat testfile #原有内容
test 30
test 30
test 30
Hello 95
Hello 95
Hello 95
Hello 95
Linux 85
Linux 85

$ uniq testfile #删除重复行后的内容
test 30
Hello 95
Linux 85

# 检查文件并删除文件中重复出现的行,并在行首显示该行重复出现的次数。使用如下命令:
$ uniq -c testfile #删除重复行后的内容
3 test 30 #前面的数字的意义为该行共出现了3次
4 Hello 95 #前面的数字的意义为该行共出现了4次
2 Linux 85 #前面的数字的意义为该行共出现了2次


# 当重复的行并不相邻时,uniq 命令是不起作用的,即若文件内容为以下时,uniq 命令不起作用:
$ cat testfile1 # 原有内容
test 30
Hello 95
Linux 85
test 30
Hello 95
Linux 85
test 30
Hello 95
Linux 85

## 方法
$ sort testfile1 | uniq
Hello 95
Linux 85
test 30

查找和比较文件的命令

  1. comm命令:比较两个已经排好序的文件(逐行比较)
  • -123表示不显示第一列(仅在f1中出现的行)、第二列(仅在f2中出现的行)、第三列(在f1与f2中出现的行)
  1. diff命令:(不要求两个文件事先排好序)
1
2
3
4
5
6
7
8
9
10
11
12
13
[root@localhost test3]# diff log2014.log log2013.log 
3c3 # 3 change 3 前者的第三行与后者的第三行
< 2014-03 # 前者
---
> 2013-03 # 后者
8c8
< 2013-07
---
> 2013-08
11,12d10 # 11 12 delete 10 ,前者11 12行有下面这些东西。10 为前一个文件的11 12 行的内容在第二个文件的第10行后缺失# 了
< 2013-11
< 2013-12

404

  1. cmp命令:(发现差异会标出差异的位置)
1
2
3
$ cmp -b ex1 ex2
ex1 ex2 differ:byte 1,line 1 is 144 d 43 #
# 意思是第一行第一字节不同,ex1上是e,编码144,ex2上是#
  1. find:(在指定的目录下查找相应的文件)
1
$ find . -name "m*.c" #在当前目录下查找以m开头.c结尾的文件。.表示当前目录。-name 选项用于根据文件名进行匹配。

复制、删除和移动文件的命令

  1. cp命令:
1
2
3
4
5
6
$ cp mfile /home/fox/exam1 # 将mfile复制到/home/fox下,并改名为exam1

$ cp -r /home/fox /home/cat # 将目录/home/fox下所有**文件及其子目录**复制到目录/home/cat中

$ cp -i /home/fox /home/cat # i是交互式的,覆盖前会提示

  1. rm命令:(删除)
1
2
3
4
5
6
7
$ rm -i test example # 交互式删除文件。test 和 example:这是要删除的两个文件名。

$ rm -r * # 递归地删除指定目录及其下属的各级子目录和相应的文件。

$ rm -f filename # Force-delete a specific file

$ rm -d empty_dir # Remove an empty directory
  • if you accidentally press Enter after:
    • rm -f (with no filename): The command will wait for input from stdin
    • rm -f * or rm -f /: Would delete ALL files (catastrophic without backups)
  1. mv命令:(对文件或者目录重命名,或者将文件从一个目录移动到另一目录中)
1
2
3
$ mv ex1 new1 # 改名字

$ mv /home/doc/* . # 把/home/doc下的所有文件移到当前目录

文件内容统计命令

  1. wc命令
1
2
3
$ wc -clw f1 f2 # -c:字节数 -l:行数 -w:字数

$ wc f1 #同上

目录及其操作命令

各种目录

404
404
404

绝对路径与相对路径

  1. 显示绝对路径
1
$ pwd
  1. 相对路径
    相对路径不唯一

创建和删除目录

  1. mkdir命令:
1
2
3
4
5
6
7
8
9
10
11
12
13
$ mkdir f1.txt # 在当前目录下创建f1.txt

$ mkdir -m 700 f1.txt # Creates a directory named test under /home/helena/ with permissions set to 700.
# Owner (7): rwx (Read + Write + Execute)
# Group (0): --- (No permissions)
# Others (0): --- (No permissions)
# Fails if /home/helena/ doesn’t exist (no parent directory auto-creation).

$ mkdir –pm 750 bin/os_
# Parent directories (e.g., bin/) are created with default permissions (usually 755).

# Only the target directory (os_) gets the specified 750 permissions.

  1. rmdir命令:
    注意:不能在子目录下删除父目录,或者在当前目录下删除当前目录。且被删目录应为空目录。
  • -p:递归删除目录dirname,当子目录删除后其父目录为空时,也一同被删除。如果有非空的目录,则该目录保留下来
  • Command to Delete Non-Empty Directories
1
rm -rf /path/to/dirname # R means Recursively 
  1. 关于rm -rf *

The command rm -rf * is a powerful and dangerous Linux/Unix command that recursively deletes all files and directories in the current working directory.

改变工作目录和显示目录内容

  1. cd命令:
1
2
3
4
5
6
7
$ cd .. # 向上移动一级

$ cd ../.. # 向上移动两级 。注意这两个文件的空格

$ cd # 切换到家目录

$ cd home/chen #切换到home/chen
  1. ls命令:(列出指定目录内容)
1
2
3
4
5
6
7
$ ls -F # 列出当前目录内容,并标出文件属性
# /,表示目录;*,表示可执行文件;@,表示符号链接文件;|,表示管道文件;=,表示socket文件

$ ls -C # 以多列形式列出目录的内容(实际上跟不加C一样)

$ ls -lai #长格式、所有文件(显示隐藏文件)、显示I节点号(每个文件或目录都有一个唯一的 inode 号,用于标识文件。
# Inode 号类似于文件的“身份证号”。)

链接文件的命令

  1. 硬链接
    创建的链接与原来的文件Inode号不变。

  2. 软链接
    创建的链接与原来的文件Inode号发生改变。

  3. 区别

符号链接(软)确实是一个新文件,它有不同的I节点号;而硬链接并没有建立新文件。
404

  • 为什么硬链接不能跨文件系统?软链接为什么可以?

硬链接直接指向文件的 inode(磁盘上的物理地址),而不同文件系统的 inode 编号是独立管理的,无法互相识别。
软链接存储的是目标文件的路径字符串(如 /mnt/usb/file.txt),不依赖 inode,因此可以跨设备。

  • 为什么不允许目录硬链接?软链接可以用于目录?

硬链接当工具(如 find、rm -r)遍历目录时,会进入无限循环:docs/ → backup/ → docs/ → backup/ → …
软链接是独立的文件,存储的是目标路径的字符串,不共享 inode。系统解析软链接时,会跳转到目标路径,不会造成循环引用。

  1. ln命令:(用来创建链接)
1
2
3
$ ln a1.txt a1.txt.link # -F为硬链接,默认为硬链接

$ ln -s a2.txt a2.txt.link # -s为软链接

改变文件或者目录存取权限的命令

Linux中有四种用户:1-当前用户(user);2-当前用户的用户组(group);3-其他用户(others);4-超级管理员(root)。其次all代表所有用户
Linux中有三种权限:r-读;w-写;e-执行

  1. chmod命令
1
2
3
4
5
$ chmod a+x ex1 # 将文件ex1改为所有用户都有可执行权限

$ chmod u=rx,g=x,o= ex1 # 其他用户无权访问

$ chmod 0664 ex1 # 代表 0 111 111 100 -rwx-rwx-r--
  1. unmask命令:(设置新建文件的掩码,默认0022)
  • 新建文件的原始权限为:0666
  • 新建目录的原始权限为:0777
  1. 若设置掩码为:0022。则上述变为0666-0022=0644;0777-0022=0755
1
2
3
# 设置掩码默认值
$ umask
0022

改变用户组和文件主的命令

  1. chgrp
1
2
# -R:递归式,将/home/wc下的文件及其子文件的用户**组**改为chenshi
$ chgrp -R chenshi /home/wc
  1. chown
    同上,不过是改变用户

联机帮助命令

  1. man
1
2
# date命令的用法
$ man date
  1. help

有关进程的命令

  1. ps
1
2
3
4
5
6
7
8
9
10
$ ps

PID TTY TIME CMD
2140 pts/0 00:00:00 bash
2159 pts/0 00:00:00 ps

# PID:进程ID号
# TTY:该进程建立时对应的终端(pts/0、pts/1、pts/2······)
# TIME:占用CPU的时间,有些命令虽然运行了很长时间,但真正使用CPU的时间往往很短
# CMD:执行进程的命令名。
  1. nice:修改进程优先级
  2. kill:杀死进程
1
$ kill 1999 # 1999为PID号码
  1. sleep:暂停进程
1
$ sleep 100 # 暂停100秒

文件的压缩与解压缩

  1. gzip:压缩文件(默认)/解压缩文件
1
2
3
4
5
6
7
8
9
$ cd /home/chen

$ gzip * # 将当前所有文件压缩

$ gzip -dv * # -d解压缩;-v显示详细信息

$ gzip -l # 列出每个压缩文件的信息,但不执行解压缩

$ gzip -v --fast * # -v显示压缩比;--fast实现快速解压
  1. unzip:对.zip文件解压缩
1
2
3
$ unzip hong.zip

$ unzip -v hong.zip # 显示有关压缩文件的信息,但不解压缩
  1. tar:归档
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ tar -cvf
$ tar –cvf test.tar test # 生成.tar文件
# -c:创建(Create)新的归档文件。
# -v:显示详细过程(Verbose)。
# -f:指定归档文件名(File)。


$ tar -xvf
$ tar –xvf test.tar # 将 test.tar 中的内容释放到当前目录。
# -x:解包(Extract)。
#-v:显示详细过程。
# -f:指定要解包的归档文件。


$ tar -cvzf
$ tar –cvzf test.tar.gz test # 将 test 文件/目录打包并 用gzip压缩,生成 .tar.gz 文件。
# -z:使用gzip压缩(Zip)
# 生成压缩后的 test.tar.gz,体积比 .tar 更小。

文本编辑

前言

  1. vi是文本编辑器;vim是vi improved
  2. 在UNIX/Linux系统中都存在vi
  3. Linux中输入vi其实就是启动了vim

vi的三种工作方式

命令方式

进入vi编辑器后,输入命令

  1. a(append):附加命令
  2. i(insert):插入命令

输入这些命令既由命令方式->输入方式

输入方式

按下输入的键来输入

按下esc由输入方式->命令方式

ex转义方式

:作为ex命令提示符,后跟命令,按下delete终止执行

进入与退出vi

进入vi

1
$ vi example.c

退出vi

  1. :wq:保存并退出
  2. :ZZ:当有改动时,才写入
  3. X:同2
  4. :q!:强制退出

命令模式下的命令

插入命令

  1. i命令:光标在哪,就在光标处的前一位置插入
  2. I命令:光标在哪,就在行首插入

附加命令

  1. a命令:光标在哪,就在光标处的后一位置插入
  2. A命令:光标在哪,就在行尾插入

打开命令(开辟新行)

  1. o:在当前行的下面新开一行
  2. O:在当前行的上面新开一行

移动光标的其他命令

404

gg到第一行
G到最后一行
nG到第n行

命令模式下移动光标

  1. l;Space;:向右移动。
    3+l == 3+Space

  2. h;BackSpace;:向左移动

  3. k;:向上移动

  4. enter;;j:向下移动

命令模式下文本修改

  1. x;X:前者向左删除;后者向右删除
    用法:3x

  2. dd:删除整行

输入模式

光标的移动

  1. 方向键:移动光标
    注意:

    关于Linux下shell界面按上下左右方向键出现ABD的问题
    这个问题有两种可能,一种是由于当前用户使用的shell是/bin/sh的原因。在添加用户的时候没有添加用户的指定shell类型,因此默认
    为/bin/sh。
    可以用shell类型命令:echo $SHELL 查看当前用户的shell类型,如果是/bin/sh,使用:chsh -s /bin/bash username或者使用
    usermod -s /bin/bash username命令修改shell类型。
    另一种是当前用户的shell类型是/bin/bash但是还是会有这个问题,这时可以在终端输入:export TERM=linux。
    这个是因为ubuntu的版本的TERM的问题。

  2. BackSpace:回退到某一位置开始重做

输入文本

即输入你想输入的文本

ex转义模式

  1. 常用命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ :20   # 移动到第20行

$ :/this # 从当前行向后查找this

$ :?thils # 向前

$ : 15 , 100 d # 删除15-100行

$ : . , +5d #删除当前行和他后面的5行

$ g/s1/p # 打印全文中含有s1的行

$ :%s / I / i / g # s->substitute 将I换为i 且是global替换

$ :set nu # 设置行号

$ :set nonu # 取消行号

$ :n # 到第n行

Linux Shell程序设计

之前写的大多数命令,shell都作为命令解释程序出现,下面将介绍Shell程序设计语言(默认为Bash)。

Shell脚本的概述、建立与执行

概述

在第一行写上#!/bin/bash表明下面的脚本是用Bash编写的

建立

使用vi编辑器

三种执行方式

1
2
3
4
5
6
7
8
# 1
$ bash < ScriptName

# 2
$ bash ScriptName para1 para2 ···

# 3-将shell脚本的权限设置为可执行,然后在提示符下直接执行它
$ ./criptName

显示与执行历史命令

显示

1
2
3
4
5
6
7
$ history
81 pwd
82 history
# 历史事件号越大,表明越是最近执行的命令

# 显示10条
$ history 10

执行

404

配置历史命令环境

1
2
3
4
5
6
7
8
chen12@ubuntu:~$ echo $HISTFILE
/home/chen12/.bash_history

# 解释:$+HISTFILE:是显示其值

$ $HISTSIZE = 600

# 解释:设置可存储600条命令

名称补全

名称补全可以补全命令与参数,但不能补全选项

别名

别名用于简化输入

1
2
3
4
5
6
7
8
9
10
11
# 别名的定义
$ alias ..='cd ..' # 注意等号间不能有空格,注意用''

# 举例
$ alias ll='ls -l'
$ my = /home/bc # 定义变量my,并赋值
$ ll $my # my表示引用变量值 # 注意:换名是在读脚本时完成的,而非运行脚本时完成的

# 取消别名
$ unalias ll # 删除别名为ll的记录
$ unalias -a # 删除所有别名

特殊字符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 通配符
# * 匹配任意字符的0次、1次、多次出现
# ? 匹配任意一个字符
# [字符组] 匹配该字符组限定的任意一个字符,!(惊叹号),**注意**如果它紧跟在一对方括号的左方括号([)之后,则表示不在一对方括号中# 所列出
的字符f[!1-9].c表示以f开头,后面一个字符不是数字1-9的.c文件名。
# ! 非

# *(),匹配括号内字符的0次、1次、多次出现
# +(),匹配括号内字符的1次、多次出现
# ?(),匹配括号内字符的0次、1次出现
# @(),匹配括号内字符的1次
# !(),非
## 注意各模式之间用|分隔开
$ ll file.*(.c|.o)

引号

  • ""即双引号括起来的内容均当作普通字符对待。但是$ \ 倒引号除外,$表示变量替换;\表示转义字符,后面可以跟$ \ " 倒引号,表示后面这个字符不作特殊处理;倒引号表示命令替换 。
1
2
3
4
5
6
7
8
9
10
11
12
13
$ ehco "current time is `data`"
current time is 2025年 03月 18日 星期二 20:32:43 PDT

$ home=$(pwd) # 等号两边不能有空格,这是shell变量赋值的要求
$ echo "home dic is $home"
home dic is /home/chen12

$ echo "file*.()"
file*.()

$ echo "current '$home'"
current '/home/chen12'

  • 单引号。由单引号括起来的字符均作为普通字符(包括转义字符)出现。
1
2
3
4
5
6
7
8
$ str='echo "directory is $home"'
$ echo $str
echo "directory is $home"
# echo$home,都失去了原有的意义

chen12@ubuntu:~$ echo 'The time is 'data',the file is $home/abc'
The time is data,the file is $home/abc

  • 倒引号。被shell解释为命令行,在执行时,会先执行命令行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
chen12@ubuntu:~$ echo current dir is `pwd`
current dir is /home/chen12

chen12@ubuntu:~$ today=`date`
chen12@ubuntu:~$ echo today is $today
today is 2025年 03月 21日 星期五 03:03:07 PDT

## 注意嵌套使用时需要使用转义符进行转义

# 转义字符可用作续行符
chen12@ubuntu:~$ 42423424\
> 2342\
> 2325555
4242342423422325555: command not found

输入、输出重定向符

执行一个shell命令时,通常会自动打开三个标准文件:标准输入文件、标准输出文件、标准出错输出文件。
404

输入重定向符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ score < file1

# score是一个可执行程序,用C语言编写

chen12@ubuntu:~$ vi a1.sh
echo hhh
echo ddd
echo sss
echo aaaaaa

chen12@ubuntu:~$ bash < a1.sh
hhh
ddd
sss
aaaaaa

$ wc < a1.sh


输出重定向

1
2
3
4
5
6
# 将指定文件的输出定向到某个文件中(原来的文件会被清楚,这是“覆盖式”写入)
chen12@ubuntu:~$ who > a1.sh
chen12@ubuntu:~$ cat a1.sh
chen12 :0 2025-03-21 02:55 (:0)


输出附加定向符

>>,原有内容不被破坏

复用输入与输出重定向

1
2
# wc -l < infile > outfile
# 统计输入的行数,将文件 infile 的内容作为 wc 的输入,将 wc 的输出结果写入文件 outfile

即时文件定向符

1
2
3
4
5
6
7
8
9
10
11
chen12@ubuntu:~$ grep "hello" << eof
> hello
> rr
> hello
> tthello
> eof
hello
hello
tthello

# 即以'eof'开头,以'eof'结尾

使用即时文件定向符的好处:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
chen12@ubuntu:~$ sort
a
q
w
e
a
e
q
w
chen12@ubuntu:~$ sort << uu
> aa
> ab
> ac
> uu
aa
ab
ac

可以看到:放入即时文件比便输入数据、边处理方便。

与文件描述字有关的重定向

标准输入、标准输出、标准错误输出的文件描述字分别为0、1、2

1
2
3
4
5
6
7
8
9
10
$ gcc m1.c 2> errfile

# 把编译过程中产生的错误信息输出到errfile中
# 注意:2与>之间不能有Space

$ command $>file
# 等价于
$ command > file 2>& 1

# 实现把标准输出和标准错误输出到同一个文件中
  • command > file 2>& 1的实现逻辑
    404

注释、管道线、后台命令

1
2
3
4
5
6
7
8
9
#!/bin/bash
# #!后面的为绝对路径名

$ ls -l $HOME | wc -l
$ ls | grep m?.c | wc -l
# wc -l 统计文件行数,即文件数目

$ gcc m1.c&
# &使之成为后台命令,仅当CPU空闲时运行后台命令

关于ls -l 与 ll在ubantu上意义不同的说明:
404

命令操作符

1
2
3
4
5
6
7
pwd ; who ; cd /da/shd ; date

# 前面的命令执行成功与否,不影响后面程序的运行

# 逻辑与&&
# 逻辑或||
$ gcc m1.c && echo yes || echo no # 作为命令是否执行成功的判断标志

Shell变量

  1. shell有两类变量:环境变量(永久),用户自定义变量(暂时,仅限于定义它的程序)

用户自定义的变量

  1. 变量名

区分大小写

  1. 变量赋值

变量名=字符串,注意等号两端没有空格,更改变量即重新赋值

  1. 引用变量值

在变量的前面加上$,不加会被认为是普通字符串。不赋值或者赋空值,会显示为空字符串。
如果含有空格之类的,需要加上双引号,否则就只识别第一个

1
2
3
4
5
6
$ s=ing
$ echo l like read$s
i like reading
# 变量的值可以作为长字符串的一部分
# 为了避免混淆,也可以
$ echo l like read${s}
  1. 命令替换
1
2
3
4
5
# 有两种形式可将命令的执行结果赋给变量

$ dir=`pwd`

$ dir=$(pwd)

数组

bash提供一维数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ declare -a arrar_name     # 数组的声明 

$ arrar_name=(var1 var2 ...) # 或者:声明+整体赋值

$ array_name[0] = var1 # 个体赋值

$ echo ${arrar_name[0]} # 个体输出

$ echo ${arrar_name[8]} # 若此项未定义,则输出空串

$ echo ${arrar_name[*]}
$ echo ${arrar_name[@]} # 这样会输出所有元素

$ unset array_name[0] # 取消第0个元素的定义

输入、输出命令

  1. read命令

read命令从键盘上读取数据,然后赋值给指定变量

1
2
3
4
5
$ read a b c
# 输入数据时,以空格或制表符为分隔符。如果输入的数据多,都算到最后一个变量上。输入数据少,则最后几个变量为空值

$ read -p "enter var" a
# 增加提示信息,p与后面的提示词必有
  1. echo命令

若echo命令带有参数e,则其后面的参数可有转义字符

1
2
3
4
5
$ echo -e "enter the file name->\c"
# \c 作用是光标不换行

$ echo -n ok
# 不换行打印ok

位置参数

1
2
3
4
5
6
$ set `pwd;ls;date`
# set是设置位置参数的值
$ echo $1 $3 ${10} ${12}

$ shift # shift移动位置参数,2变成1,3变成2等
$ shift 4 #相当于4个shift

算术运算

let

let "j=i*6+2"等价于((j=i*6+2))

1
2
3
4
5
6
7
8
9
10
11
12
# 当命令中有特殊字符时,用双引号
$ let "v=6|5"
$ echo $v

$ ((v=6|5))
$ echo $v

$ echo "((12*9))"
$ "((12*9))"

$ echo "$((12*9))"
$ 108

流程控制语句

if语句

if-then-else-fi,一个if对应一个fi

条件测试

  1. 使用test命令

if test -f "$1"

  1. 用[]

[ -f "$1" ]注意中括号前后各有一个空格

  1. 用[[]]

同理,最好用双中括号

  1. 常用的文件测试符号形式与功能

-e:文件存在与否
-f:文件存在且是普通文件
-d:文件存在且是目录文件

  1. 字符串测试运算符形式与功能

s1 = s2:两字符串相等,注意等号左右的空格
s1 != s2:两字符串不等
s1 < s2:字典顺序

  1. 数值测试运算符形式与功能

-eq
-ne
-lt
-le
-gt
-ge

!:非
-a:与
-o:或
():括号前加\使括号失去了意义

  1. 番外

command1 && echo "success" || echo "no"可判断命令1是否执行成功

case语句

404

*)为default
dir|path)为或

while语句

404

until语句

与while语句相反

for语句

  1. 值表方式

for day in Monday Friday

  1. 算术表达式

for ((i=1;i<=$1;i++))

其他

break;
continue;
exit;
select;

函数

1
2
3
4
[function]function_name(){

}
# 其中function可省略

一些简单命令

jobs:列出当前未完成的作业

kill:向进程发送指定信号

1
2
3
4
5
$ kill -9 1893
#立刻终止PID为1893的进程

$ kikk -15 1893
#让其正常终止

两种遍历方式

1
2
3
4
5
6
7
# 脚本 test.sh
for arg in "$*"; do
echo "Argument: $arg"
done

# shift
shift times

gcc—C语言编译系统

gcc的编译过程

预处理、编译、汇编、链接。

  1. 预处理

gcc -E source.c -o output.i
E为只进行预处理
-o output.i为指定输出文件

#include 被替换为头文件内容。

#define 宏被展开。

#ifdef / #endif 等条件编译被处理。

  1. 编译

gcc -S source.i -o output.s
S为只进行编译

C 代码被转换为 CPU 相关的汇编指令(如 x86、ARM 等架构)。

  1. 汇编

gcc -c source.s -o output.o

汇编代码(如 mov, call 等)被转换为机器码(.o 文件,ELF 或 COFF 格式)。

  1. 链接

gcc source.o -o myprogram # 链接标准库

合并多个 .o 文件。

  1. 一步完成

gcc hello.c -o hello

番外

文件系统概念

注意:之所以Linux能支持多种文件系统,是因为Linux采用虚拟文件系统技术。

  • 虚拟文件系统(Virtual File System/VFS)是操作系统和真正的文件系统之间的接口。它将各种不同的文件系统的信息进行转化,形成统一的格式后交给Linux操作系统处理,并将处理结果还原为原文件系统格式。对于Linux而言,它所处理的是统一的虚拟文件系统,而不需要知道文件所采用的真实的文件系统。由于采用了虚拟文件系统技术,Linux支持的文件系统,包括DOS的msdos、Windows XP的fat32、光盘的iso9660,还有实现网络共享的NFS等文件系统。

404

做到了什么

  • 当你通过 Linux 的命令(如 ls 或 cat)访问这些设备时,不需要为每种文件系统编写不同的代码。

  • VFS 提供统一的系统调用(如 open()、read()、write()),应用程序只需与 VFS 交互,无需关心底层文件系统的差异。

对比无 VFS 的情况

  • 如果没有 VFS,应用程序需要针对每种文件系统实现不同的代码路径(如 if (is_fat32) { … } else if (is_ntfs) { … }),导致复杂性和维护成本极高。

职位

  1. 前端:Vue
  2. 后端:Spring Boot
  3. 测试:测试工具
  4. 售前:demo版本
  5. 运维与交付:对客户培训

工具

  1. finalshell:国产远程控制Linux软件

管道

  1. “|”是Linux管道命令操作符,简称管道符。使用此管道符“|”可以将两个命令分隔开,“|”左边命令的输出就会作为“|”右边命令的输入,此命令可连续使用,第一个命令的输出会作为第二个命令的输入,第二个命令的输出又会作为第三个命令的输入,依此类推。

404