Shell IO重定向与exec的使用介绍

mac2025-08-15  12

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接: https://blog.csdn.net/beautysleeper/article/details/52595163

注:该文章例子来自于网络的收集和整理,附带本人注解。

①I/O重定向的常用用法

符号 意义 cmd1 | cmd2 管道符,将cmd1的标准输出作为cmd2的标准输入。 > filename 将标准输出写到文件filename之中。 < filename 将文件filename的内容读入到标准输入之中。 >>filename 将标准输出写到文件filename之中,若filename文件已存在,则将标准输出追加到filename已有内容之后。 >|filename 即使noclobber选项已开启,仍然强制将标准输出写到文件filename之中,即将filename文件覆盖掉。 n>|filename 即使noclobber选项已开启,仍然使用FD为n以截断模式打开文件filename。 n> filename 使用FD为n以截断模式打开文件filename。 n< filename 使用FD为n以读取模式打开文件filename。 n>>filename 使用FD为n以追加模式打开文件filename。 << delimiter 此处文档(Here-document)。 123456789101112

②exec命令的介绍

1,通过文件描述符打开或关闭文件。 2,将文件重定向到标准输入,及将标准输出重定向到文件。 3exec命令重新设置了I/O重定向,要恢复为原来的I/O指向,还得需要使用exec命令显示指定。 exec用法: &n :代表描述符代表的文件。 > < :代表以什么形式使用描述符。 exec 8<&2 :描述符8以读取方式打开标准错误对应的文件。 exec &>log:把标准输入错误打开文件logexec 8<&- :关闭描述符8。 123456789

1):run.sh脚本使用exec将stdin(标准输入)重定向到文件

root@37C:~# cat run.sh #!/bin/bash exec 8<&0 # 标准输入默认是指向了键盘,复制一份到 8 中,8 也指向了键盘。 exec 0< hfile # 1. 使用标准输入打开文件hfile。 read a # 2. read 将从stdin中读取命令。 read b echo "---------------------------" echo $a echo $b echo "Close FD 8:" exec 0<&8 8<&- #将FD-8 copy到标准输入(恢复指向键盘),否则,标准输入还是指向hfile。 echo -n "Pls. Enter Data: " #这里,标准输入重新指向了键盘。 read c #需要我们手工键入字符。 echo $c exit 0 123456789101112131415

结果输出:

# hfile文件的内容。 root@37C:~# cat hfile value1 value2 root@37C:~# ./run.sh --------------------------- value1 value2 Close FD 8: Pls. Enter Data: value3 value3 root@37C:~# 1234567891011121314

2):run.sh脚本将stdout重定向到文件

root@37C:~# cat run.sh #!/bin/bash exec 8>&1 # 打开 FD-8,并使它指向显示器。 exec 1> log # 将标准输出指向log文件 echo '------redirect to log file-------' # 这部分输出会保存在log文件里面。 echo "Output of date command:" date echo "Output of df command:" df sleep 5s # 先睡 5 秒,以区分两个结果输出。 exec 1>&8 8>&- echo "------termincal display:-------" echo "Output of date command" date echo "Output of df command" df 1234567891011121314151617

结果输出:

root@37C:~# ./run.sh ------termincal display:------- Output of date command 20160920日 星期二 16:02:08 CST Output of df command 文件系统 1K-块 已用 可用 已用% 挂载点 udev 355032 0 355032 0% /dev tmpfs 75824 3020 72804 4% /run /dev/sda1 17673004 6600160 10152064 40% / tmpfs 379108 132 378976 1% /dev/shm tmpfs 5120 4 5116 1% /run/lock tmpfs 379108 0 379108 0% /sys/fs/cgroup tmpfs 75824 48 75776 1% /run/user/1000 root@37C:~# cat log ------redirect to log file------- Output of date command: 20160920日 星期二 16:02:03 CST Output of df command: 文件系统 1K-块 已用 可用 已用% 挂载点 udev 355032 0 355032 0% /dev tmpfs 75824 3020 72804 4% /run /dev/sda1 17673004 6600160 10152064 40% / tmpfs 379108 132 378976 1% /dev/shm tmpfs 5120 4 5116 1% /run/lock tmpfs 379108 0 379108 0% /sys/fs/cgroup tmpfs 75824 48 75776 1% /run/user/1000 root@37C:~# 123456789101112131415161718192021222324252627

3):&>file将stdout和stderr重定向到文件

#!/bin/bash exec 8>&1 9>&2 #FD 1复制到FD 8,FD 2复制到FD 9 exec &> log #&>符号将stdout和stderr重定向到文件log ls z* #错误写入文件log date #输出写入文件log exec 1>&8 2>&9 8<&- 9<&- #恢复关闭操作 echo "-----------------" echo "Close FD 8 and 9:" ls z* date 1234567891011

4):普通例子

_1):使用文件描述符3以读取模式打开文件run.py

root@37C:~# exec 3<run.py root@37C:~# cat <&3 #!/usr/bin/python3 # -*- coding:utf-8 -*- import logging logging.basicConfig(level=logging.INFO) s = '0' n = int(s) logging.info('n = %d' % n) print(10 / n) root@37C:~# 123456789101112

_2):使用文件描述符4以截断模式打开文件log

root@37C:~# exec 4>log root@37C:~# echo " I think befor I am" 1>&4 root@37C:~# cat log I think befor I am root@37C:~# 12345

_3):使用文件描述符5以追加模式打开文件log

root@37C:~# exec 5>>log # 这里echo 使用'>'而非'>>'来进行追加。 root@37C:~# echo 'say again: I think before I am!' >&5 root@37C:~# cat log I think befor I am say again: I think before I am! 123456

_4):exec 执行后的观察。

# FD 8,9也指向了FD 0,1所指向的文件。 root@37C:~# exec 9>&1 root@37C:~# exec 8<&0 root@37C:~# ls -l /proc/self/fd/ 总用量 0 lrwx------ 1 root root 64 9月 21 21:03 0 -> /dev/pts/2 lrwx------ 1 root root 64 9月 21 21:03 1 -> /dev/pts/2 lrwx------ 1 root root 64 9月 21 21:03 2 -> /dev/pts/2 lr-x------ 1 root root 64 9月 21 21:03 3 -> /proc/20455/fd lrwx------ 1 root root 64 9月 21 21:03 8 -> /dev/pts/2 lrwx------ 1 root root 64 9月 21 21:03 9 -> /dev/pts/2 1234567891011

③ 尝试题

# 尝试一下的操作结果会如何? root@37C:~# exec 0<run.sh 12 <link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-e9f16cbbc2.css" rel="stylesheet"> </div>
最新回复(0)