zoukankan      html  css  js  c++  java
  • Linux Shell exec绑定重定向

    shell 中的 exec 两种用法

      1.exec 命令 ;命令代替shell程序,命令退出,shell 退出;比如 exec ls

      2.exec 文件重定向,可以将文件的重定向就看为是shell程序的文件重定向 比如 exec 5</dev/null;exec 5<&-

      shell的内建命令exec将并不启动新的shell,而是用要被执行命令替换当前的shell进程,并且将老进程的环境清理掉,而且exec命令后的其它命令将不再执行。
      因此,如果你在一个shell里面,执行exec ls那么,当列出了当前目录后,这个shell就自己退出了,因为这个shell进程已被替换为仅仅执行ls命令的一个进程,执行结束自然也就退出了。为了避免这个影响我们的使用,一般将exec命令放到一个shell脚本里面,用主脚本调用这个脚本,调用点处可以用bash a.sh,(a.sh就是存放该命令的脚本),这样会为a.sh建立一个sub shell去执行,当执行到exec后,该子脚本进程就被替换成了相应的exec的命令。
      source命令或者".",不会为脚本新建shell,而只是将脚本包含的命令在当前shell执行。
      不过,要注意一个例外,当exec命令来对文件描述符操作的时候,就不会替换shell,而且操作完成后,还会继续执行接下来的命令。
      exec 3<&0:这个命令就是将操作符3也指向标准输入。

      另外,这个命令还可以作为find命令的一个选项,如下所示:
      (1)在当前目录下(包含子目录),查找所有txt文件并找出含有字符串"bin"的行
        find ./ -name “.txt" -exec grep “bin” {} ;
      (2)在当前目录下(包含子目录),删除所有txt文件
        find ./ -name ".txt” -exec rm {} ;
    先总结一个表:

    exec命令 作用
    exec ls 在shell中执行ls,ls结束后不返回原来的shell中了
    exec <file 将file中的内容作为exec的标准输入
    exec >file 将file中的内容作为标准写出
    exec 3<file 将file读入到fd3中
    sort <&3 fd3中读入的内容被分类
    exec 4>file 将写入fd4中的内容写入file中
    ls >&4 Ls将不会有显示,直接写入fd4中了,即上面的file中
    exec 5<&4 创建fd4的拷贝fd5
    exec 3<&- 关闭fd3

      1、exec 执行程序  

      虽然exec和source都是在父进程中直接执行,但exec这个与source有很大的区别,source是执行shell脚本,而且执行后会返回以前的shell。而exec的执行不会返回以前的shell了,而是直接把以前登陆shell作为一个程序看待,在其上经行复制。

      举例说明:

     1 root@localhost:~/test#exec ls
     2 
     3 exp1 exp5 linux-2.6.27.54 ngis_post.sh test xen-3.0.1-install
     4 
     5 root@localhost:~/test#exec >text
     6 
     7 root@localhost:~/test#ls
     8 
     9 root@localhost:~/test#pwd
    10 
    11 root@localhost:~/test#echo “hello”
    12 
    13 root@localhost:~/test#exec>/dev/tty
    14 
    15 root@localhost:~/test#cat text
    16 
    17 exp1
    18 
    19 exp5
    20 
    21 linux-2.6.27.54
    22 
    23 ngis_post.sh
    24 
    25 test
    26 
    27 text
    28 
    29 xen-3.0.1-install
    30 
    31 /root/test
    32 
    33 hello
    34 
    35 root@localhost:~/test#

      Exec >text 是将当前shell的标准输出都打开到text文件中

     1 root@localhost:~/test#cat test
     2 
     3 ls
     4 
     5 Pwd
     6 
     7 root@localhost:~/test#bash
     8 
     9 root@localhost:~/test#exec <test
    10 
    11 root@localhost:~/test#ls
    12 
    13 exp1 exp5 linux-2.6.27.54 ngis_post.sh test text xen-3.0.1-install
    14 
    15 root@localhost:~/test#pwd
    16 
    17 /root/test
    18 
    19 root@localhost:~/test#
    20 
    21 root@localhost:~/test#exit #自动执行

      exec的重定向

      先上我们进如/dev/fd/目录下看一下:

    1 root@localhost:~/test#cd /dev/fd
    2 
    3 root@localhost:/dev/fd#ls
    4 
    5 0 1 2 255

      默认会有这四个项:0是标准输入,默认是键盘。

      1是标准输出,默认是屏幕/dev/tty

      2是标准错误,默认也是屏幕

      255

      当我们执行exec 3>test时:

    1 root@localhost:/dev/fd#exec 3>/root/test/test
    2 
    3 root@localhost:/dev/fd#ls
    4 
    5 0 1 2 255 3
    6 
    7 root@localhost:/dev/fd#

      看到了吧,多了个3,也就是又增加了一个设备,这里也可以体会下linux设备即文件的理念。这时候fd3就相当于一个管道了,重定向到fd3中的文件会被写在test中。关闭这个重定向可以用exec 3>&-。

     1 root@localhost:/dev/fd#who >&3
     2 
     3 root@localhost:/dev/fd#ls >&3
     4 
     5 root@localhost:/dev/fd#exec 3>&-
     6 
     7 root@localhost:/dev/fd#cat /root/test/te
     8 
     9 test text
    10 
    11 root@localhost:/dev/fd#cat /root/test/test
    12 
    13 root tty1 2010-11-16 01:13
    14 
    15 root pts/0 2010-11-15 22:01 (192.168.0.1)
    16 
    17 root pts/2 2010-11-16 01:02 (192.168.0.1)
    18 
    19 0
    20 
    21 1
    22 
    23 2
    24 
    25 255
    26 
    27 3

    应用举例

    1 exec 3<test
    2 
    3 while read -u 3 pkg

      do

      echo “$pkg”

      done

      系统调用exec是以新的进程去代替原来的进程,但进程的PID保持不变。因此,可以这样认为,exec系统调用并没有创建新的进程,只是替换了原来进程上下文的内容。原进程的代码段,数据段,堆栈段被新的进程所代替。

      一个进程主要包括以下几个方面的内容:

      (1)一个可以执行的程序

      (2) 与进程相关联的全部数据(包括变量,内存,缓冲区)

      (3)程序上下文(程序计数器PC,保存程序执行的位置)

      exec是一个函数簇,由6个函数组成,分别是以excl和execv打头的。
      执行exec系统调用,一般都是这样,用fork()函数新建立一个进程,然后让进程去执行exec调用。我们知道,在fork()建立新进程之后,父进各与子进程共享代码段,但数据空间是分开的,但父进程会把自己数据空间的内容copy到子进程中去,还有上下文也会copy到子进程中去。而为了提高效率,采用一种写时copy的策略,即创建子进程的时候,并不copy父进程的地址空间,父子进程拥有共同的地址空间,只有当子进程需要写入数据时(如向缓冲区写入数据),这时候会复制地址空间,复制缓冲区到子进程中去。从而父子进程拥有独立的地址空间。而对于fork()之后执行exec后,这种策略能够很好的提高效率,如果一开始就copy,那么exec之后,子进程的数据会被放弃,被新的进程所代替。

      exec与system的区别
      (1) exec是直接用新的进程去代替原来的程序运行,运行完毕之后不回到原先的程序中去。

      (2) system是调用shell执行你的命令,system=fork+exec+waitpid,执行完毕之后,回到原先的程序中去。继续执行下面的部分。

      总之,如果你用exec调用,首先应该fork一个新的进程,然后exec. 而system不需要你fork新进程,已经封装好了。

  • 相关阅读:
    进程的经典同步问题
    数学余数在计算机的用途
    7.货仓选址 绝对值不等式
    6. 排队打水 排序不等式
    5.合并果子 Huffman树
    4.区间覆盖 区间问题
    3.区间分组 区间问题
    2.最大不相交区间数量 区间问题
    1.区间选点 区间问题
    26.拆分-Nim游戏 博弈论
  • 原文地址:https://www.cnblogs.com/Reverse-xiaoyu/p/13122404.html
Copyright © 2011-2022 走看看