shell文件描述符fd

时间:2019-04-16 23:59:05  来源:igfitidea点击:

打开文件描述符进行读写

Bash支持以下语法来打开文件,以便通过文件描述符读取和写入:

exec fd<>fileName
  1. 如果没有指定fd,则使用文件描述符0。
  2. 如果文件不存在,就创建它。
  3. 这种语法对更新文件很有用。

示例

#!/bin/bash
FILENAME="/tmp/out.txt"
# 打开文件描述符# 3进行读写
exec 3<>$FILENAME

# Write to file
echo "Today is $(date)" >&3
echo "shell脚本" >&3
echo "theitroad" >&3

# 关闭文件描述符3
exec 3>&-

从文件描述符(fd)读取

可以使用read命令从键盘或文件中读取数据。
其中使用 -u选项可以从文件描述符而不是键盘读取。

语法

read -u fd var1 var2 ... varN

或者
使用while循环读取整个文件的行:

while IFS= read -u fd -r line
do
    command1 on $line
    command2 on $line
    ..
    ....
    commandN
done

示例

#!/bin/bash
# 将文件描述符3分配给输入文件
exec 3< /etc/resolv.conf

# 将文件描述符4分配给输出文件
exec 4> /tmp/output.txt
 
# 使用read命令读取fd3对应的文件的第一行
read -u 3 a b

# 在屏幕上显示
echo "Data read from fd # 3:"
echo $a $b

# 写入一些数据到我们的输出文件
echo "Writing data fd#4 ... "
echo  "Field #1 - $a " >&4
echo  "Field #2 - $b " >&4

# 关闭文件描述符
exec 3<&-
exec 4<&-

执行命令并将输出发送到文件描述符

语法

command-name >& fd
./shell-script >& fd

例如,将“free -m”命令的输出发送到fd4

#!/bin/bash
exec 4> /tmp/out.txt
free -m >&4

示例 - 收集系统信息的Shell脚本

#!/bin/bash
# get date in dd-mm-yyyy format
NOW=$(date +"%d-%m-%Y")

# create output file name
OUTPUT="/tmp/sysinfo.$NOW.log"

# Assign the fd 3 to $OUTPUT file
exec 3> $OUTPUT

# Write date, time and hostname
echo "---------------------------------------------------"  >&3
echo "System Info run @ $(date) for $(hostname)"  >&3
echo "---------------------------------------------------"  >&3

echo "****************************" >&3
echo "*** Installed Hard Disks ***" >&3
echo "****************************" >&3
fdisk -l | egrep "^Disk /dev" >&3

echo "************************************" >&3
echo "*** File System Disk Space Usage ***"  >&3
echo "************************************" >&3
df -H >&3

echo "***********************" >&3
echo "*** CPU Information ***"  >&3
echo "***********************" >&3
grep 'model name' /proc/cpuinfo  | uniq | awk -F: '{ print }' >&3

echo "*****************************" >&3
echo "*** Operating System Info ***"  >&3
echo "*****************************" >&3
uname -a >&3
[ -x /usr/bin/lsb_release ] && /usr/bin/lsb_release -a  >&3 || echo "/usr/bin/lsb_release not found." >&3

echo "**************************************" >&3
echo "*** Amount Of Free And Used Memory ***"  >&3
echo "**************************************" >&3
free -m >&3

echo "************************************" >&3
echo "*** Top 10 Memory Eating Process ***"  >&3
echo "************************************" >&3
ps -auxf | sort -nr -k 4 | head -10 >&3

echo "**********************************" >&3
echo "*** Top 10 CPU Eating Process  ***"  >&3
echo "**********************************" >&3
ps -auxf | sort -nr -k 3 | head -10 >&3

echo "******************************************" >&3
echo "*** Network Device Information [eth0]  ***"  >&3
echo "******************************************" >&3
netstat -i | grep -q eth0 && /sbin/ifconfig eth0 >&3 || echo "eth0 is not installed" >&3


echo "******************************************" >&3
echo "*** Network Device Information [eth1]  ***"  >&3
echo "******************************************" >&3
netstat -i | grep -q eth1 && /sbin/ifconfig eth1 >&3 || echo "eth1 is not installed" >&3

echo "********************************" >&3
echo "*** Wireless Device [wlan0]  ***"  >&3
echo "********************************" >&3
netstat -i | grep -q wlan0 && /sbin/ifconfig wlan0 >&3 || echo "wlan0 is not installed" >&3

echo "*************************************" >&3
echo "*** All Network Interfaces Stats ***" >&3
echo "*************************************" >&3
netstat -i >&3
echo "System info wrote to $OUTPUT file."

关闭文件描述符(fd)

语法:

exec fd<&-