24、Linux 终端 I/O 与行为控制全解析

Linux 终端 I/O 与行为控制全解析

1. 终端基础概念

在 Linux 系统中,终端是我们与系统交互的重要工具,它有多种形式,如 X 窗口系统中的终端窗口、通过 Ctrl + Alt + F1 至 F7 访问的七个终端、老式串行终端、拨号终端以及远程终端(如 Secure Shell,即 SSH)。终端主要分为 TTY(TeleTYpewriter 的缩写)和 PTY(Pseudo - TeletYpewriter 的缩写)两类。
- TTY :是硬件终端,例如通过 Ctrl + Alt + F1 至 F7 访问的控制台或串行控制台。
- PTY :是伪终端,通过软件模拟实现。像 xterm、rxvt、Konsole、Gnome Terminal 等程序,或者如 tmux 这样的终端复用器都属于 PTY,远程终端如 SSH 也可看作 PTY。

了解终端的相关信息并对其进行控制,有助于我们编写更优质的软件,例如在密码提示时隐藏输入内容。

1.1 技术要求

在学习过程中,我们需要一些常用工具,如 GNU 编译器集合(GCC)、Make 工具和通用的 Makefile,此外还需要一个名为 screen 的程序。如果系统中尚未安装该程序,可以使用系统的包管理器进行安装:
- 对于 Debian/Ubuntu 系统: sudo apt - get install screen
- 对于 CentOS/Fedora 系统: sudo dnf install screen

所有相关代码示例可从 此处 下载,也可查看 代码演示视频

2. 查看终端信息

2.1 准备工作

此操作无需特殊要求,仅使用系统中已安装的标准程序即可。

2.2 操作步骤

  • 确定当前使用的 TTY/PTY :在终端中输入 tty 命令,系统会显示当前使用的 TTY 或 PTY。例如:
$> tty
/dev/pts/24
  • 检查对应文件类型 :使用 ls -l file 命令检查该终端对应的文件类型,它属于字符特殊文件。示例如下:
$> ls -l /dev/pts/24
crw--w---- 1 jake tty 136, 24 jan  3 23:19 /dev/pts/24
$> file /dev/pts/24
/dev/pts/24: character special (136/24)
  • 查看终端属性 :使用 stty -a 命令查看终端的所有属性,包括终端的大小(行数和列数)、速度(在串行终端、拨号等场景中重要)以及各种 Ctrl 键组合对应的功能等。示例如下:
$> stty -a
speed 38400 baud; rows 14; columns 88; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U;
eof = ^D; eol = M - ^?; eol2 = M - ^?;
swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V;
discard = ^O; min = 1; time = 0;
 - parenb - parodd - cmspar cs8 hupcl - cstopb cread - clocal - crtscts
 - ignbrk brkint - ignpar - parmrk - inpck - istrip - inlcr - igncr icrnl ixon - ixoff - iuclc
ixany imaxbel iutf8
opost - olcuc - ocrnl onlcr - onocr - onlret - ofill - ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok - echonl - noflsh - xcase - tostop - echoprt echoctl
echoke - flusho - extproc
  • 查看其他终端属性 :若要查看其他终端的属性,需确保该终端的所有者是当前登录用户,否则会出现权限拒绝错误。示例如下:
$> stty -F /dev/pts/33
speed 38400 baud; line = 0;
lnext = <undef>; discard = <undef>; min = 1;
time = 0; - brkint - icrnl ixoff - imaxbel iutf8
 - icanon - echo
$> stty -F /dev/tty2
stty: /dev/tty2: Permission denied

2.3 工作原理

在 Linux 系统中,可能有大量用户通过 TTY 或 PTY 登录。过去,多使用硬件终端(TTY)通过串行线路连接到计算机,如今硬件终端已较为少见,更多是通过 SSH 登录或使用终端程序。

/dev/pts/24 为例,PTY 由主设备(PTM)和从设备(PTS)两部分组成,我们连接的是从设备(PTS)。主设备负责打开或创建伪终端,而我们实际使用的是从设备。

stty -a 输出中,以减号开头的选项表示禁用,如 -parenb ;无减号的选项表示启用,如 cs8 -parenb 用于生成奇偶校验位并期望输入中也有相应校验位,常用于拨号连接和串行通信; cs8 则将字符大小设置为 8 位。 stty 程序可用于查看和设置终端属性。

2.4 相关参考

可通过 man 1 tty man 1 stty 命令获取更多相关信息。

3. 使用 stty 更改终端设置

3.1 准备工作

此操作无需特殊要求。

3.2 操作步骤

  • 关闭终端回显 :在终端中输入 stty -echo 命令关闭回显,此时输入的内容将不会显示,但命令仍可正常执行。示例如下:
$> stty -echo
$> whoami jake
$>
  • 重新开启终端回显 :输入 stty echo 命令重新开启回显。注意,输入该命令时不会显示输入内容。
$> stty echo
$> whoami
jake
  • 更改特殊键序列 :可以将 EOF 字符从默认的 Ctrl + D 重新绑定为单个点(.)。
$> stty eof .

输入单个点(.)后,当前终端将退出或注销。重新启动终端或重新登录后,设置将恢复为默认值。
- 保存终端设置 :先进行必要的设置更改,如将 EOF 设置为点,然后使用 stty --save 命令保存设置,该命令会输出一串十六进制数字,可将其重定向到文件中。

$> stty eof .
$> stty --save
5500:5:bf:8a3b:3:1c:7f:15:2e:0:1:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0
$> stty --save > my - tty - settings
  • 恢复终端设置 :注销后重新登录,输入单个点不会有任何反应。使用以下命令从保存的文件中恢复设置:
$> stty $(cat my - tty - settings)

再次输入单个点,终端将退出或注销。

3.3 工作原理

终端通常是“哑”设备,需要大量设置才能正常工作,这是早期硬件电传打字机遗留下来的特性。 stty 程序用于设置终端设备的属性,减号开头的选项表示禁用,无减号的选项表示启用。目前,保存 TTY 设置的有效方法是将设置保存到文件中,以便后续恢复。

4. 调查 TTY 和 PTY 并进行消息发送

4.1 操作步骤

  • 准备工作 :打开三到四个终端窗口,如果未使用 X 窗口系统,可在多个 TTY 上登录;若使用远程服务器,可多次登录。
  • 查看登录用户信息 :在其中一个终端中输入 who 命令,可查看所有登录用户的信息,包括使用的 TTY/PTY 以及登录时间。示例如下:
$> who
root     tty1         Jan  5 16:03
jake     pts/0        Jan  5 16:04 (192.168.0.34)
jake     pts/1        Jan  5 16:04 (192.168.0.34)
jake     pts/2        Jan  5 16:04 (192.168.0.34)
  • 查看用户当前使用的程序 :使用 w 命令可查看每个终端上用户当前使用的程序。
$> w
16:09:33 up 7 min,  4 users,  load average: 0.00, 0.16, 0.13
USER  TTY    FROM          LOGIN@  IDLE  JCPU   PCPU WHAT
root  tty1   -             16:03   6:05  0.07s  0.07s -bash
jake  pts/0  192.168.0.34  16:04   5:25  0.01s  0.01s -bash
jake  pts/1  192.168.0.34  16:04   0.00s 0.04s  0.01s w
jake  pts/2  192.168.0.34  16:04   5:02  0.02s  0.02s -bash
  • 确定当前使用的终端 :输入 tty 命令确定当前使用的终端。
$> tty
/dev/pts/1
  • 向其他终端发送消息 :由于终端在文件系统中以文件形式表示,可使用重定向向其他终端发送消息。例如,向 /dev/pts/2 终端发送消息:
$> echo "Hello" > /dev/pts/2

但如果向其他用户(如 root)登录的终端发送消息,可能会因权限问题失败。

$> echo "Hello" > /dev/tty1
 - bash: /dev/tty1: Permission denied
  • 使用 write 程序发送消息 :使用 mesg 程序允许或禁止接收消息。以 root 用户为例,允许接收消息:
#> tty
/dev/tty1
#> whoami
root
#> mesg y

其他用户可使用 write 程序向该终端发送消息:

$> write root /dev/tty1
Hello! How are you doing?
Ctrl + D
  • 向所有终端发送消息 :root 用户可使用 wall 命令向所有登录用户发送消息,例如通知即将重启:
#> wall "The machine will be rebooted later tonight"

3.3 工作原理

因为终端在文件系统中以文件形式存在,所以可以像操作文件一样向其发送消息,但需要遵循文件的权限规则。 write 程序允许用户在对方允许的情况下相互发送消息, wall 命令用于向所有终端发送消息,root 用户可向禁止接收消息的用户发送消息。

3.4 相关参考

可通过 man 1 write man 1 wall man 1 mesg 命令获取更多相关信息。

5. 检查是否为 TTY

5.1 准备工作

需要 GCC 编译器、Make 工具和通用的 Makefile,通用 Makefile 可从 此处 下载。

5.2 操作步骤

  • 编写程序 :创建一个名为 ttyinfo.c 的文件,编写以下代码:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
int main(void)
{
    if ( (isatty(STDOUT_FILENO) == 1) )
    {
        printf("It's a TTY with the name %s\n",
            ttyname(STDOUT_FILENO));
    }
    else
    {
        perror("isatty");
    }
    printf("Hello world\n");
    return 0;
}
  • 编译程序 :在终端中输入 make ttyinfo 命令编译程序。
$> make ttyinfo
gcc -Wall -Wextra -pedantic - std=c99    ttyinfo.c   -o ttyinfo
  • 运行程序
    • 不进行重定向运行程序,会输出终端名称和 “Hello world”:
$> ./ttyinfo
It's a TTY with the name /dev/pts/10
Hello world
- 将文件描述符 1 重定向到文件,程序会输出错误信息,但 “Hello world” 会被重定向到文件中:
$> ./ttyinfo > my - file
isatty: Inappropriate ioctl for device
$> cat my - file
Hello world
- 将文件描述符 1 重定向到 `/dev/stdout`,程序正常运行:
$> ./ttyinfo > /dev/stdout
It's a TTY with the name /dev/pts/10
Hello world
- 将文件描述符 1 重定向到自己的终端设备,程序正常运行:
$> tty
/dev/pts/10
$> ./ttyinfo > /dev/pts/10
It's a TTY with the name /dev/pts/10
Hello world
- 打开第二个终端,获取其 TTY 名称(如 `/dev/pts/26`),将程序输出重定向到该终端:
$> ./ttyinfo > /dev/pts/26

当前终端无输出,第二个终端会显示程序输出。

5.3 工作原理

STDOUT_FILENO 宏代表整数 1,即文件描述符 1。当使用 > 重定向标准输出时,实际上是重定向文件描述符 1。如果将文件描述符 1 重定向到文件,由于文件不是终端, isatty() 函数会返回错误信息。当将文件描述符 1 重定向回 /dev/stdout 或其他终端时,程序会正常运行。

5.4 相关参考

可通过 man 3 isatty man 3 ttyname 命令获取更多相关信息。

6. 创建 PTY

6.1 操作步骤

使用 C 程序创建 PTY,PTY 由主设备(PTM)和从设备(PTS)两部分组成。程序将创建 PTY 并在当前终端打印从设备的路径,之后可使用 screen 程序连接到该 PTS 进行操作。

6.2 代码示例(待补充完整代码)

// 此处应补充创建 PTY 的代码
6.3 工作原理

程序通过特定的系统调用创建 PTY 的主设备和从设备,主设备负责管理和控制,从设备供用户使用。创建完成后,可通过 screen 程序连接到从设备进行交互。

6.4 后续操作

连接到 PTS 后,可在其中输入命令,实现与终端的交互。

通过以上内容,我们全面了解了 Linux 终端的相关知识,包括终端的类型、查看和更改终端设置、向其他终端发送消息以及创建 PTY 等操作,这些知识将帮助我们更好地与 Linux 系统进行交互。

6. 创建 PTY(续)

6.2 代码示例

以下是一个完整的 C 程序示例,用于创建 PTY 并打印从设备的路径:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>

int main() {
    int master_fd;
    char *slave_name;

    // 创建 PTY
    master_fd = posix_openpt(O_RDWR | O_NOCTTY);
    if (master_fd == -1) {
        perror("posix_openpt");
        return 1;
    }

    // 解锁 PTY
    if (grantpt(master_fd) == -1) {
        perror("grantpt");
        close(master_fd);
        return 1;
    }

    // 使 PTY 从设备可用
    if (unlockpt(master_fd) == -1) {
        perror("unlockpt");
        close(master_fd);
        return 1;
    }

    // 获取从设备的名称
    slave_name = ptsname(master_fd);
    if (slave_name == NULL) {
        perror("ptsname");
        close(master_fd);
        return 1;
    }

    // 打印从设备的路径
    printf("PTY slave device: %s\n", slave_name);

    // 可以在这里添加代码,使用 screen 连接到从设备
    // 例如:system("screen <slave_name>");

    close(master_fd);
    return 0;
}
6.3 工作原理
  • posix_openpt 函数用于打开一个新的伪终端主设备,并返回其文件描述符。
  • grantpt 函数用于授予对伪终端从设备的访问权限。
  • unlockpt 函数用于解锁伪终端从设备,使其可以被使用。
  • ptsname 函数用于获取伪终端从设备的名称。

通过这些步骤,程序成功创建了一个 PTY,并获取了从设备的路径。

6.4 后续操作

连接到 PTS 后,可在其中输入命令,实现与终端的交互。例如,使用 screen 程序连接到从设备:

$ screen /dev/pts/X  # X 为实际的从设备编号

连接成功后,你可以在 screen 会话中输入命令,就像在普通终端中一样。

7. 终端操作总结

为了更好地理解和掌握前面介绍的终端操作,下面通过一个表格进行总结:
| 操作类型 | 命令/程序 | 功能描述 | 示例 |
| ---- | ---- | ---- | ---- |
| 查看终端信息 | tty | 显示当前使用的 TTY 或 PTY | $ tty |
| | ls -l file | 检查终端对应文件的类型 | $ ls -l /dev/pts/24
$ file /dev/pts/24 |
| | stty -a | 查看终端的所有属性 | $ stty -a |
| 更改终端设置 | stty -echo | 关闭终端回显 | $ stty -echo |
| | stty echo | 开启终端回显 | $ stty echo |
| | stty eof . | 更改 EOF 字符 | $ stty eof . |
| | stty --save | 保存终端设置 | $ stty --save > my - tty - settings |
| | stty $(cat my - tty - settings) | 恢复终端设置 | $ stty $(cat my - tty - settings) |
| 调查 TTY 和 PTY 并发送消息 | who | 查看所有登录用户的信息 | $ who |
| | w | 查看每个终端上用户当前使用的程序 | $ w |
| | echo "message" > /dev/pts/X | 向指定终端发送消息 | $ echo "Hello" > /dev/pts/2 |
| | mesg y | 允许接收消息 | # mesg y |
| | write user /dev/ttyX | 向指定用户的终端发送消息 | $ write root /dev/tty1 |
| | wall "message" | 向所有登录用户发送消息 | # wall "The machine will be rebooted later tonight" |
| 检查是否为 TTY | isatty() ttyname() | 检查文件描述符是否为终端,并获取终端名称 | 见 ttyinfo.c 示例 |
| 创建 PTY | C 程序 | 创建 PTY 并获取从设备路径 | 见前面的 C 程序示例 |

8. 终端操作流程图

下面是一个 mermaid 格式的流程图,展示了常见的终端操作流程:

graph TD;
    A[开始] --> B{选择操作};
    B --> C[查看终端信息];
    B --> D[更改终端设置];
    B --> E[调查 TTY 和 PTY 并发送消息];
    B --> F[检查是否为 TTY];
    B --> G[创建 PTY];
    C --> H[tty 命令];
    C --> I[ls -l 和 file 命令];
    C --> J[stty -a 命令];
    D --> K[stty -echo 关闭回显];
    D --> L[stty echo 开启回显];
    D --> M[stty eof . 更改 EOF 字符];
    D --> N[stty --save 保存设置];
    D --> O[stty $(cat settings) 恢复设置];
    E --> P[who 命令查看用户信息];
    E --> Q[w 命令查看用户程序];
    E --> R[echo 重定向发送消息];
    E --> S[mesg 允许接收消息];
    E --> T[write 发送消息];
    E --> U[wall 向所有用户发送消息];
    F --> V[编写 ttyinfo.c 程序];
    F --> W[编译运行程序];
    G --> X[编写创建 PTY 的 C 程序];
    G --> Y[编译运行程序];
    H --> Z[结束];
    I --> Z;
    J --> Z;
    K --> Z;
    L --> Z;
    M --> Z;
    N --> Z;
    O --> Z;
    P --> Z;
    Q --> Z;
    R --> Z;
    S --> Z;
    T --> Z;
    U --> Z;
    V --> Z;
    W --> Z;
    X --> Z;
    Y --> Z;

9. 总结与展望

通过本文的学习,我们全面了解了 Linux 终端的相关知识,包括终端的类型(TTY 和 PTY)、查看和更改终端设置、向其他终端发送消息、检查是否为 TTY 以及创建 PTY 等操作。这些知识不仅有助于我们更好地与 Linux 系统进行交互,还能帮助我们编写更高效、更安全的终端相关程序。

在未来的学习和实践中,我们可以进一步探索终端的高级功能,如自定义终端配置、开发终端应用程序等。同时,我们也可以关注终端安全问题,确保在使用终端时保护好个人信息和系统安全。

希望本文能为你在 Linux 终端编程和操作方面提供有价值的参考,让你在 Linux 系统中更加得心应手。

内容概要:本文系统研究了移相控制桥LLC谐振变换器的工作特性,深入分析其在不同工况下的运行机理性能表现,并基于Simulink平台构建了完整的仿真模型进行验证。文章详细阐述了LLC谐振变换器的电路拓扑结构、工作原理、关键参数设计方法以及移相控制策略的实现机制,重点对电压增益特性、转换效率、软开关实现条件等核心性能指标进行了仿真分析,面评估了系统在宽输入电压范围内的稳定性、动态响应能力及高效运行区间。; 适合人群:适用于电力电子、电气工程及其自动化等相关专业的高校研究生、科研机构研究人员以及从事高频开关电源、DC-DC变换器设计的工程技术人员;要求读者具备扎实的电路理论基础和一定的Simulink仿真应用经验。; 使用场景及目标:①深入掌握LLC谐振变换器的基本原理数学建模方法;②理解并应用移相控制策略以提升高效率DC-DC变换器的性能;③通过仿真实践优化谐振腔参数(如谐振电感、励磁电感、谐振电容)开关频率配置,提高电源系统的整体能效、功率密度和可靠性,服务于实际工程中的电源产品开发性能验证。; 阅读建议:建议读者结合提供的Simulink仿真模型同步操作,重点探究谐振元件参数变化对系统增益曲线和ZVS软开关实现条件的影响,尝试调节移相角开关频率以观察动态响应过程,从而深化对LLC变换器高频软开关特性和控制策略的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值