首页 > 代码库 > exec和source的简单区别
exec和source的简单区别
Linux种exec和.(Source)都可以同样来执行程序或者脚本,要区别二者区别,首先了解linux下的2种命令,内部命令和外部命令:
内部命令是特殊文件格式.def实现的。
外部命令是通过系统调用或者独立程序实现的。
其次shell执行脚本的时候有两种方式:
1、当前shell下执行
2、启动子shell在子shell种执行
当shell启动子shell时候,通过fork创建进程子进程,首先子进程会继承父进程的很多属性,而非共享,再复制了父进程数据之后,2者就基本没有关系了,简单表示就是 父进程属性→子进程。fork函数和一般的函数不同,在他成功创建出子进程之后会返回两个值,一个返回给父进程中的pid变量(值为子进程ID),一个返回给自进程中的pid变量(值为0)当然,如果fork失败了,则只需要返回给父进程pid变量一个-1(子进程不存在)。子进程确实复制了父进程的数据,叫做继承了父进程的部分属性,这样一来,子进程和父进程中的变量就不是同一个变量了。
在shell种脚本得的第一行通常是/bin/bash,这种方式就是使用subshell执行,见《shell脚本编程》p36。当shell打开一个可执行文件时,系统调用fork创建进程,用于执行程序,内核执行飞编译程序
返回错误"NOT excutable format file”,shell收到错误信息启动一个新shell(shell副本)来执行,
#!(shabang)用于告诉内核使用哪个shell来执行。
现在我们查看系统帮助文档怎么介绍的:
source(.): Read and execute commands from filename in the current shell environment and return the exit status of the last command exe- cuted from filename. exec: If command is specified, it replaces the shell. No new process is created.
由此可见source执行的时候是当前shell环境下执行,执行完成后把状态返回给当前shell。
exec执行时候会关闭当年shell进程,并且fork一个相同pid的shell进程来执行,系统调用新的exec的process来替代原来的进程执行。从表面上看没有新的进程创建,原来进程的代码段、数据段、堆栈都被新的process所代替。
exec系统调用过程
fork()执行创建一个new_process,程序执行exec系统调用,fork()执行后父子进程共享代码段,数据空间分开,父进程copy自己的数据空间内容和上下文到子进程。采用写时copy的策略:在创建子进程时不会不copy父进程的地址空间,共用,当子进程写入数据时,这时候copy空间到子进程,这种策略提高效率并且执行fork()完执行exec后,子进程的数据会被新的进程代替。
文件描述符FD(file-descriptor)
文件在打开时候系统给每一个打开的文件分配用于维护的描述符,这通常包括系统打开文件描述符表,进程级的文件描述符表(文件操作符标志和文件句柄的引用),文件系统i-node表。(以后会单独写一个对内核源码的解释)
exec的用法表(参考的百度)
exec cmd | 执行cmd,结束后不反回原shell |
exec <file | file内容作为exec的stdin |
exec >file | exec中内容作为stdout |
exec 3<file | file内容读到FD3中 |
sort <&3 | FD3读入内容被分类 |
exec 4>file | FD4中内容写入到file |
cmd >&4 | cmd输出重定向到FD4 |
exec 5<&4 | FD4走FD5的通道 |
exec 3<&- | 关闭FD3 |
Example:
1、使用exec cmd
[yemo@localhost /]$ exec ls bin dev home lib64 media opt root selinux sys usr boot etc lib lost+found mnt proc sbin srv tmp var Connection closed by foreign host. Disconnected from remote host(cent6mini_eth0) at 03:59:43. Type `help‘ to learn how to use Xshell prompt. [c:\~]$
执行完成后关闭了shell
2、使用exec控制FD1(stdout)
[root@localhost tmp]# echo ‘im lovin it‘> echo.txt [root@localhost tmp]# echo echo.txt echo.txt [root@localhost tmp]# ls /dev/fd/ 0 1 2 3 [root@localhost tmp]# exec >echo.txt [root@localhost tmp]# ls [root@localhost tmp]# echo "i did it" [root@localhost tmp]# cat echo.txt cat: echo.txt: input file is output file [root@localhost tmp]# exec >/dev/tty [root@localhost tmp]# cat echo.txt echo echo.txt haha netstat pass rc re.txt sed_passwd sudoers yum.log i did it
FD1重定向到文件,FD1重定向用exec指向到时文件echo.txt的管道,标准输出到传到文件echo.txt,最后重定向FD1到设备tty(屏幕),打印实验结果
3、使用exec控制FD0
i did it [root@localhost tmp]# echo "echo i lovin it">echo [root@localhost tmp]# cat echo echo i lovin it [root@localhost tmp]# exit
回车自动输出了exit
4、创建FD4
[root@localhost yemo]# ls /dev/fd/ 0 1 2 3 [root@localhost tmp]# exec 4>4.txt [root@localhost tmp]# ls /dev/fd/ 0 1 2 3 4 [root@localhost tmp]# echo "i feel i lose my heart" >&4 [root@localhost tmp]# ls >&3 bash: 3: Bad file descriptor [root@localhost tmp]# ls >&4 [root@localhost tmp]# exec 4>&- [root@localhost tmp]# cat 4.txt i feel i lose my heart 4.txt echo echo.txt haha netstat pass rc re.txt sed_passwd sudoers yum.log
exec创建FD4指向文件4.txt,系统创建了FD4管道,通过管道4的内容到会传到文件4.txt中,关闭管道,否则文件占用无法打开。
本文出自 “庭前夜末空看雪” 博客,请务必保留此出处http://12550795.blog.51cto.com/12540795/1927907
exec和source的简单区别