Linux Shell脚本中read、重定向和文件句柄和进程数目控制

Linux Shell脚本中read、重定向和文件句柄和进程数目控制

1、把重定向作为read的输入

read可以从标准输入读取一行,下面就使用read配合重定向把文件作为read的标注输入。

#!/bin/bash
#name:     links.sh
# Revision:    1.1
# Date:        2017//
# Author:      linuxidc
# Email:       [email protected]
# Website:     
# Description: Print the ip-links
# Notes:       
# -------------------------------------------------------------------------------
# Copyright:   2017 (c) linuxidc
# License:     GPL
#
  
while read line ;do
    echo "line=$line"
    sleep 2
done </home/linuxidc/model.txt        #把文件作为read的的输入
  
unset line

接下来运行一下

root@linuxidc:/home/yemo# bash  file_des.sh 
line=#!/bin/bash
line=#name:     links.sh
line=# Revision:    1.1
line=# Date:        2017/6/
line=# Author:      linuxidc
line=# Email:       [email protected]
line=# Website:
line=# Description: Print the ip-links
line=# Notes:
line=# -------------------------------------------------------------------------------

输出了我的bash头部模板文件的内容

 2、再话文件描述符

 文件在打开时候系统给每一个打开的文件分配用于维护的描述符,这通常包括系统打开文件描述符表,进程级的文件描述符表(文件操作符标志和文件句柄的引用),文件系统i-node表。

    基本用法

exec fd<>file                 #创建一个文件句柄                                   
exec fd>&-   or   exec -fd<&     #关闭文件句柄

 创建文件描述符后在/proc/PID/fd中新建,通过$$查看当前shell的PID。

root@linuxidc:/home/yemo# cd /proc/$$/fd                     
root@linuxidc:/proc/6833/fd# ls
0  1  2  255

 给文件/home/linuxidc/model.txt创建一个描述符fd6

root@linuxidc:/proc/6833/fd# exec 6<>/home/linuxidc/model.txt
root@linuxidc:/proc/6833/fd# ls
0  1  2  255  6

打开fd6,查看内容

root@linuxidc:/proc/6833/fd# cat 6
#!/bin/bash
#name:     links.sh
# Revision:    1.1
#后面挺长就省略了,这不是重点

我们可以通过fd6,读写文件model.txt

root@linuxidc:/proc/6833/fd# echo "hello girl" >>6
root@linuxidc:/proc/6833/fd# tail -1 6
hello girl

如果删除文件,fd6会怎么样呢

root@linuxidc:/proc/6833/fd# stat -c %i /home/linuxidc/model.txt   #先查看下inode
128531
root@linuxidc:/proc/6833/fd# stat -c %i 6
49938
root@linuxidc:/proc/6833/fd# rm /home/linuxidc/model.txt 
root@linuxidc:/proc/6833/fd# ls
0  1  2  255  6

fd6显示成红色,表示文件已经不存在了,我们打开一下

root@linuxidc:/proc/6833/fd# cat 6
#!/bin/bash
#name:     links.sh
# Revision:    1.1
#此处省略很多行
hello girl

依旧可以打开,文件的删除只是删除的上级目录的存在的一个文件名,当文件在使用时候,并不会释放inode,只要block的数据没被覆盖都可以找回来,这里文件不大直接打开fd6重定向回去就好。

3、通过fd把文件内容传给read

root@linuxidc:/proc/6833/fd# exec 6>&-            #关闭文件句柄
root@linuxidc:/proc/6833/fd# ls
0  1  2  255

新建脚本测试一下

使用-u选项: 

-u fdread from file descriptor FD instead of the standard input

#!/bin/bash
#filename:     file_des.sh
# Revision:    1.1
# Date:        2017-06-09
# Author:      linuxidc
# Email:       [email protected]
# QQ:      787743742
# Website:     
# Description: 
# Notes:       
# -------------------------------------------------------------------------------
# Copyright:   2017 (c) linuxidc
# License:     GPL
  
exec 6<>/home/linuxidc/model.txt                       #创建文件句柄(fd6)
  
while read -u 6 line ;do                   #循环读取文件
    echo "line=$line"
    sleep 2
done 
exec 6>&-                          #文件用完,关闭文件句柄
unset line                         #自定义变量,结束释放

执行结果:

root@linuxidc:/home/yemo# bash file_des.sh 
line=#!/bin/bash
line=#name:     links.sh
line=# Revision:    1.1
line=# Date:        2017/6/
line=# Author:      linuxidc
line=# Email:       [email protected]            #后面的内容就省略了

 表面上看来这么做和单独使用重定向效果一样,但是当程序需要多个输入时候,单独的重定向只能让read读取单独一个文件内容无法为每个单独指定输入。

4、通过文件句柄创建多进程

 read -u 读取文件描述符的方式读取字符串

 设置文件描述符中回车数量为预设进程数目

 通过循环建立多进程

#!/bin/bash
#filename:     mproc.sh
# Revision:    1.1
# Date:        2017-06-09
# Author:      linuxidc
# Email:       [email protected]
# QQ:      787743742
# Website:     
# Description: This is use for test shell multiprocess
# Notes:       
# -------------------------------------------------------------------------------
# Copyright:   2017 (c) linuxidc
# License:     GPL
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# you should have received a copy of the GNU General Public License
#
# If any changes are made to this script, please mail me a copy of the changes
# -------------------------------------------------------------------------------
#Version 1.0
#
  
main_sub() {
    local loop_time=$(( $1 % 7 ))
    echo -e "$i\t----\t---$loop_time begin"
    sleep $loop_time
    echo -e "$i\t-----\t$loop_time end"
}
tmp_file="/tmp/.fifo-$$"
mkfifo $tmp_file                                       #创建fifo文件用于进程通信   
exec 6<>$tmp_file                                      #创建文件句柄6为管道
rm -f $tmp_file
  
  
my_thread=6                                           #限制进程数
runtime=50
  
for (( i=0 ; i < $my_thread ; i++ )) ; do
    echo
done >&6                                           #循环写入回车符到管道
  
for (( i=0 ; i < $my_thread ; i++ )) ; do
      read -u 6                                    #进程数量控制
        {
            main_sub $i
            echo >&6      #每次函数执行完写入一个回车符,保证进程数目是指定的
        }&                                       #后台运行
done
wait                                              #父进程等待子进程结束后再退出
  
exec 6<&-
exit 0

相关推荐