设为首页 收藏本站
查看: 1097|回复: 0

linux 应用程序里面调用shell

[复制链接]

尚未签到

发表于 2015-4-29 07:10:42 | 显示全部楼层 |阅读模式
  在Linux的应用程序里面调用我的shell(这玩意功能实在太强大)的办法有很多种一般来说有fork()、exec*()、pipe、system()其中又以system()
  调用很少方便,现在加以说明。
  
     #include
  
     #include
  
     int main()
  
     {
  
     system(“ifconfig eth0 10.17.28.1”);
  
     //system(“./ifconfig.sh”);使用你的脚本shell路径要注意
  
     return 0;
  
     }
    //------------------------------------------------------------------------------------------------------------------------------------------------------
  exec*
  方法二: exec( )函数族(转)   
      下面我们来看看一个进程如何来启动另一个程序的执行。在Linux中要使用exec函数族。系统调用execve()对当前进程进行替换,替换者为一个指定的程序,其参数包括文件名(filename)、参数列表(argv)以及环境变量(envp)。exec函数族当然不止一个,但它们大致相同,在 Linux中,它们分别是:execl,execlp,execle,execv,execve和execvp,下面我只以execlp为例,其它函数究竟与execlp有何区别,请通过manexec命令来了解它们的具体情况。
  一个进程一旦调用exec类函数,它本身就"死亡"了,系统把代码段替换成新的程序的代码,废弃原有的数据段和堆栈段,并为新程序分配新的数据段与堆栈段,唯一留下的,就是进程号,也就是说,对系统而言,还是同一个进程,不过已经是另一个程序了。(不过exec类函数中有的还允许继承环境变量之类的信息。)
  那么如果我的程序想启动另一程序的执行但自己仍想继续运行的话,怎么办呢?那就是结合fork与exec的使用。 下面一段代码显示如何启动运行其它程序:
  
     char command[256];
  
     void main()
  
     {
  
     int rtn; /*子进程的返回数值*/
  
     while(1)
  {
  /* 从终端读取要执行的命令 */
  printf( ">" );
  fgets( command, 256, stdin );
  command[strlen(command)-1] = 0;
  if ( fork() == 0 )
  {
  /* 子进程执行此命令 */
  execlp( command, command );
  /* 如果exec函数返回,表明没有正常执行命令,打印错误信息*/
  perror( command ); exit( errorno ); }
  else
  {
  /* 父进程, 等待子进程结束,并打印子进程的返回值 */
  wait ( &rtn );
  printf( " child process return %d\n",. rtn );
  }
  }
  }
    此程序从终端读入命令并执行之,执行完成后,父进程继续等待从终端读入命令。熟悉DOS和WINDOWS系统调用的朋友一定知道
  DOS/WINDOWS 也有exec类函数,其使用方法是类似的,但DOS/WINDOWS还有spawn类函数,因为DOS是单任务的系统,它只能将"父进程"驻留在机器内再执行"子进程",这就是spawn类的函数。WIN32已经是多任务的系统了,但还保留了spawn类函数,WIN32中实现spawn函数的方法同前述 UNIX中的方法差不多,开设子进程后父进程等待子进程结束后才继续运行。UNIX在其一开始就是多任务的系统,所以从核心角度上讲不需要spawn类函数。
  /------------------------------------------------------------------------------------------------------------------------------------------------------
  system 是在单独的进程中执行命令,完了还会回到你的程序中。   
而exec函数是直接在你的进程中执行新的程序,新的程序会把你的程序覆盖,除非调用出错,否则你再也回不到exec后面的代码,就是说你的程序就变成了exec调用的那个程序了.
  /------------------------------------------------------------------------------------------------------------------------------------------------------
  
     #include      
#include      
#include      
int main(int argc, char *argv[]) {      
    char *envp[] = { "PATH=/tmp", "USER=lei", "STATUS=testing", NULL };      
    char *argv_execv[] = { "echo", "excuted by execv", NULL };      
    char *argv_execvp[] = { "echo", "executed by execvp", NULL };      
    char *argv_execve[] = { "env", NULL };      
    if (fork() == 0) {      
        if (execl(&quot;/bin/echo&quot;, &quot;echo&quot;, &quot;executed by execl&quot;, NULL) < 0)      
            perror(&quot;Err on execl&quot;);      
    }      
    if (fork() == 0) {      
        if (execlp(&quot;echo&quot;, &quot;echo&quot;, &quot;executed by execlp&quot;, NULL) < 0)      
            perror(&quot;Err on execlp&quot;);      
    }      
    if (fork() == 0) {      
        if (execle(&quot;/usr/bin/env&quot;, &quot;env&quot;, NULL, envp) < 0)      
            perror(&quot;Err on execle&quot;);      
    }      
    if (fork() == 0) {      
        if (execv(&quot;/bin/echo&quot;, argv_execv) < 0)      
            perror(&quot;Err on execv&quot;);      
    }      
    if (fork() == 0) {      
        if (execvp(&quot;echo&quot;, argv_execvp) < 0)      
            perror(&quot;Err on execvp&quot;);      
    }      
    if (fork() == 0) {      
        if (execve(&quot;/usr/bin/env&quot;, argv_execve, envp) < 0)      
            perror(&quot;Err on execve&quot;);      
    }      
    return 0;      
}
    /------------------------------------------------------------------------------------------------------------------------------------------------------
  程序里调用了2 个Linux 常用的系统命令,echo和env。echo会把后面跟的命令行参数原封不动的打印出来,env用来列出所有环境变量。   
由于各个子进程执行的顺序无法控制,所以有可能出现一个比较混乱的输出–各子进程打印的结果交杂在一起,而不是严格按照程序中列出的次序。   
最常见的错误:   
大家在平时的编程中,如果用到了exec 函数族,一定记得要加错误判断语句。因为与其他系统调用比起来,exec很容易受伤,被执行文件的位置,权限等很多因素都能导致该调用的失败。   
最常见的错误是:   
1)找不到文件或路径,此时errno 被设置为ENOENT;   
2)数组argv和envp忘记用NULL结束,此时errno被设置为EFAULT;   
3)没有对要执行文件的运行权限,此时errno被设置为EACCES。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-61654-1-1.html 上篇帖子: Shell调试篇 下篇帖子: 抓包NC提交拿SHELL详细教程
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表