热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Linux中exec系列函数的应用

这段时间在研究linux中用户登陆和shell执行程序的原理。我们知道,shell命令分为内部命令和外部命令,内部命令有诸如cd,history,exi

这段时间在研究linux中用户登陆和shell执行程序的原理。我们知道,shell命令分为内部命令和外部命令,内部命令有诸如cd,history,exit,echo等,常见的外部命令有ls,ping,netstat等,通过type命令可以查看一个命令是内部命令还是外部命令。当执行的命令是一个内部命令是,shell直接执行;那么shell是如何执行一个外部命令的呢?

Shell本身也是一个程序,程序之间调用的方式也有很多,例如popen,但shell成功的执行一个外部命令,要满足以下条件:
1,首先是shell能调用这个程序,这个是必须的前提。
2,第二是shell必须要等待外部程序执行完毕才能返回。
3,第三是外部程序执行时,shell必须要把所有的执行权限交给外部命令,且外部命令需要继承shell的状态,如当前工作目录,控制终端,根目录等等。

实际上在linux中,shell执行外部命令都是以子进程的方式执行,在通过pstree看到linux的进程树,如下:

  • [root@home ~]# pstree
  • systemd-+-2*[agetty]
  • |-avahi-daemon---avahi-daemon
  • |-avahi-dnsconfd
  • |-crond
  • |-dbus-daemon
  • |-haveged
  • |-ifplugd
  • |-master---pickup
  • |-python
  • |-rngd
  • |-sshd-+-3*[sshd]
  • | `-sshd---bash---pstree
  • |-systemd---(sd-pam)
  • |-systemd-journal
  • |-systemd-logind
  • |-systemd-udevd
  • `-wpa_supplicant

可以看到pstree属于bash的子进程。那么,shell执行外部命令的原理是什么呢?
当shell执行一个外部命令是,第一步是fork出一个子进程,shell获取传递进来的参数,然后子进程调用一种exec函数执行另一个程序,子进程执行的程序完全替换为新程序,因为exec不创建新的进程,所以前后的进程ID不会改变。下面代码可以用来模拟shell执行外部程序:

  • #!/usr/bin/env python
  • import os,sys
  • if sys.argv[1:]:
  • pid=os.fork()
  • else:
  • sys.exit(0)
  • if not pid:
  • filename=sys.argv[1]
  • argv1=filename
  • argvs=",".join(sys.argv[2:])
  • os.execlp(filename,argv1,argvs)
  • os.waitpid(pid,0)

把此文件保存为ba,增加执行权限,然后运行./ba ping www.hitoy.org,程序执行正常,运行pstree,发现有python产生一个ping的子程序。

Linux上,一个程序调用另外程序经常会采用这种先fork然后exec的方式。再来看一下exec,exec是linux上的一组函数,一共有6个,如下:

int execl(const char *path, const char *arg, …);
int execlp(const char *file, const char *arg, …);
int execle(const char *path, const char *arg, …, char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);

需要注意的是,上面的函数中,第一个参数path必须为路径名,filename可以是路径名也可以是文件名,当为文件名时,系统会在PATH环境变量中查找这个文件。另外一点需要注意的是,传递的arg值,必须从第0个参数开始都传递,也就是必须连同cmdline一起把所有参数传递给这个函数。


推荐阅读
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 本文介绍了在RHEL 7中的系统日志管理和网络管理。系统日志管理包括rsyslog和systemd-journal两种日志服务,分别介绍了它们的特点、配置文件和日志查询方式。网络管理主要介绍了使用nmcli命令查看和配置网络接口的方法,包括查看网卡信息、添加、修改和删除配置文件等操作。 ... [详细]
  • Python15行代码实现免费发送手机短信,推送消息「建议收藏」
    Python15行代码实现免费发 ... [详细]
  • 第七课主要内容:多进程多线程FIFO,LIFO,优先队列线程局部变量进程与线程的选择线程池异步IO概念及twisted案例股票数据抓取 ... [详细]
  • RouterOS 5.16软路由安装图解教程
    本文介绍了如何安装RouterOS 5.16软路由系统,包括系统要求、安装步骤和登录方式。同时提供了详细的图解教程,方便读者进行操作。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • 开源Keras Faster RCNN模型介绍及代码结构解析
    本文介绍了开源Keras Faster RCNN模型的环境需求和代码结构,包括FasterRCNN源码解析、RPN与classifier定义、data_generators.py文件的功能以及损失计算。同时提供了该模型的开源地址和安装所需的库。 ... [详细]
  • HashMap的相关问题及其底层数据结构和操作流程
    本文介绍了关于HashMap的相关问题,包括其底层数据结构、JDK1.7和JDK1.8的差异、红黑树的使用、扩容和树化的条件、退化为链表的情况、索引的计算方法、hashcode和hash()方法的作用、数组容量的选择、Put方法的流程以及并发问题下的操作。文章还提到了扩容死链和数据错乱的问题,并探讨了key的设计要求。对于对Java面试中的HashMap问题感兴趣的读者,本文将为您提供一些有用的技术和经验。 ... [详细]
  • 超级简单加解密工具的方案和功能
    本文介绍了一个超级简单的加解密工具的方案和功能。该工具可以读取文件头,并根据特定长度进行加密,加密后将加密部分写入源文件。同时,该工具也支持解密操作。加密和解密过程是可逆的。本文还提到了一些相关的功能和使用方法,并给出了Python代码示例。 ... [详细]
  • Python脚本编写创建输出数据库并添加模型和场数据的方法
    本文介绍了使用Python脚本编写创建输出数据库并添加模型数据和场数据的方法。首先导入相应模块,然后创建输出数据库并添加材料属性、截面、部件实例、分析步和帧、节点和单元等对象。接着向输出数据库中添加场数据和历程数据,本例中只添加了节点位移。最后保存数据库文件并关闭文件。文章还提供了部分代码和Abaqus操作步骤。另外,作者还建立了关于Abaqus的学习交流群,欢迎加入并提问。 ... [详细]
  • Python教学练习二Python1-12练习二一、判断季节用户输入月份,判断这个月是哪个季节?3,4,5月----春 ... [详细]
  • 从批量eml文件中提取附件的Python代码实现方法
    本文介绍了使用Python代码从批量eml文件中提取附件的实现方法,包括获取eml附件信息、递归文件夹下所有文件、创建目的文件夹等步骤。通过该方法可以方便地提取eml文件中的附件,并保存到指定的文件夹中。 ... [详细]
  • 查找给定字符串的所有不同回文子字符串原文:https://www ... [详细]
  • 很多时候在注册一些比较重要的帐号,或者使用一些比较重要的接口的时候,需要使用到随机字符串,为了方便,我们设计这个脚本需要注意 ... [详细]
author-avatar
用户rsvowi2rvt
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有