進程的標準輸入輸出
當主進程fork或exec子進程,文件描述符被繼承,因此0,1,2句柄也被繼承,從而使得telnet等服務,可以做到間接調用別的shell或程序。比如如果是遠程登錄使用的zsh,那么其會重定向到相應的pts
$ ps|grep zsh234671 pts/4 00:00:03 zsh
$ cd /proc/234671/fd
$ ls -la
total 0
dr-x------ 2 wsl wsl 0 Jul 6 15:13 .
dr-xr-xr-x 9 wsl wsl 0 Jul 6 15:13 ..
lrwx------ 1 wsl wsl 64 Jul 6 15:13 0 -> /dev/pts/4
lrwx------ 1 wsl wsl 64 Jul 6 15:13 1 -> /dev/pts/4
lrwx------ 1 wsl wsl 64 Jul 6 15:13 2 -> /dev/pts/4
...
進程在轉為守護進程時,可以經0,1,2句柄重定向到/dev/null,做到不輸出任何信息。
可以使用dump2可以實現重定向功能:
```c
fd = open("./test.txt",O_CREAT|O_RDWR, S_IRWXU );
dup2(fd, STDOUT_FILENO); //將STDOUT_FILENO文件描述符 指向 fd文件描述符 指向的文件;即將標準輸出 重定向到fd指向的文件‘
//該程序就能將hahahha寫在指定的test.txt文件中了
printf("hahahahaha");
close(fd);
備注:
STDOUT_FILENO、STDIN_FILENO是int型的文件描述符,是非負整數,屬于沒有buffer的I/O;一般定義為0, 1, 2 ,在<unistd.h>定義。
/* Standard file descriptors. */
#define STDIN_FILENO 0 /* Standard input. */
#define STDOUT_FILENO 1 /* Standard output. */
#define STDERR_FILENO 2 /* Standard error output. */
open()系統函數,返回的是目前未被占用的最小的文件描述符
文件描述符對應的函數是open() read() write() close()等;
stdout stdin stderr 是FILE 類型的文件指針;屬于標準I/O,在<stdio.h>。
所以可以使用:fprintf(stdout, “hahahah”);
fopen()庫函數,返回的是FILE 類型的文件指針
FILE類型的文件指針,對應的函數是 fopen() fgets() fputs() fprintf() fclose() fgetc() fputc()等
可以寫一個信號處理函數,將輸出在不同終端間切換。或者通過重定向標準輸出+無名管道的方式,實現將子進程的輸出用more顯示。
終端屬性
通過終端屬性,可以禁用回顯,
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>int main() {int fd = STDIN_FILENO; // 使用標準輸入作為終端設備的文件描述符// 獲取當前終端屬性struct termios old_attr;if (tcgetattr(fd, &old_attr) == -1) {perror("tcgetattr");exit(EXIT_FAILURE);}// 備份舊的終端屬性struct termios new_attr = old_attr;// 修改終端屬性new_attr.c_lflag &= ~ECHO; // 禁用回顯// 設置新的終端屬性if (tcsetattr(fd, TCSANOW, &new_attr) == -1) {perror("tcsetattr");exit(EXIT_FAILURE);}// 讀取用戶輸入并打印char input[100分];printf("Enter your password: ");fgets(input, sizeof(input), stdin);printf("Your password: %s", input);// 恢復之前的終端屬性if (tcsetattr(fd, TCSANOW, &old_attr) == -1) {perror("tcsetattr");exit(EXIT_FAILURE);}return 0;
}
使用stty -echo就能關閉回顯,再使用stty echo打開
使用getty打開一個終端
使用tty查看當前是哪個終端。
pi@link:/boot$ tty
/dev/ttyS0
pi@link:/boot$ sudo su
[sudo] password for pi:
root@link:/boot# tty
/dev/pts/0
root@link:/boot# who
pi ttyS0 2024-04-23 22:05
pi pts/0 2024-04-23 23:04
參考
linux 終端設置及讀寫