shell-exec

来源:互联网 发布:mac docker vs pd 编辑:程序博客网 时间:2024/06/05 15:56


例子

exec 3<>hello.txt # 以读写方式绑定到文件描述符"3"

echo "hello exec" >&3 # 写入"hello exec",如果之前有内容,这里将会从文件开头进行覆盖

echo "hello world" >>&3 # 写入"hello world“,新的一行!

exec 3>&- # 关闭写,禁止写,然而,实际上它也不能读了~

# 如果是exec 3<&-,关闭读,同时它也不能写了~

实现一个线程写,一个线程读。

 #!/bin/bash
start_time=`date +%s`              #定义脚本运行的开始时间
#[ -e /tmp/fd1 ] || mkfifo /tmp/fd1 #创建有名管道
#exec 3<>/tmp/fd1                   #创建文件描述符,以可读(<)可写(>)的方式关联管道文件,这时候文件描述符3就有了有名管道文件的所有特性
#rm -rf /tmp/fd1                    #关联后的文件描述符拥有管道文件的所有特性,所以这时候管道文件可以删除,我们留下文件描述符来用就可以了

temp_fifo_file=$$.info        #以当前进程号,为临时管道取名  
mkfifo $temp_fifo_file        #创建临时管道  
exec 3<>$temp_fifo_file       #创建标识为6,可以对管道进行读写  
rm $temp_fifo_file            #清空管道内容  

{
for ((i=1;i<=10;i++))
  do
    read -u 3    line                       #代表从管道中读取一个令牌
  {
        sleep 1                #sleep 1用来模仿执行一条命令需要花费的时间(可以用真实命令来代替)
        echo 'success'$line       
    #    echo >&3                   #代表我这一次命令执行到最后,把令牌放回管道
   }
   done
}&

for ((i=1;i<=10;i++))
do
        let num=i+100
        echo $num
        echo $num >&3                   #&3代表引用文件描述符3,这条命令代表往管道里面放入了一个"令牌"
         echo xxxx;
                sleep 2
done

wait
 
stop_time=`date +%s`  #定义脚本运行的结束时间
 
echo "TIME:`expr $stop_time - $start_time`"
exec 3<&-                       #关闭文件描述符的读
exec 3>&-                       #关闭文件描述符的写


exec命令的介绍

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

结果输出:
# hfile文件的内容。
root@37C:~# cat hfile
value1
value2

root@37C:~# ./run.sh
---------------------------
value1
value2
Close FD 8:
Pls. Enter Data: value3
value3
root@37C:~#

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

结果输出:
root@37C:~# ./run.sh
------termincal display:-------
Output of date command
2016年 09月 20日 星期二 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:
2016年 09月 20日 星期二 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:~#
0 0