在linux中的shell执行命令与进程创建

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

shell是什么?

维基百科:Unix shell也叫做命令行界面,它是Unix操作系统下传统的用户和计算机的交互界面。用户直接输入命令来执行各种各样的任务。

现在的shell不止这些功能,不过,这些与本文无关。

shell中命令的执行过程?

启动shell,本身就是创建一个进程。在shell中运行命令的时候,shell进程会以自己为模板,创建(fork)一个新的进程。这个新建的进程对shell中输入的命令进行处理,处理完之后新进程结束自己的生命,等待shell进程进行回收。具体来说,就是:

  1. shell进程调用fork()这一系统调用来创建了一个子进程。
  2. 父进程(也就是shell进程)调用wait()这一系统调用后进行等待,直到新建的子进程结束。
  3. 子进程调用exec()这一系统调用来执行shell中输入的命令,执行完成后,调用exit()这一系统调用来结束生命。
  4. 父进程的wait()回收信息,释放子进程的PCB,彻底销毁子进程。

shell是如何实现的?

下面是《Unix/Linux编程实践教程》中的代码。

#define MAXARGS 20 
#define ARGLEN 100 

main()
{
    char *arglist[MAXARGS+1];
    int numargs; 
    char argbuf[ARGLEN]; 
    char *makestring();

    numargs = 0;
    while ( numargs < MAXARGS )
    {
        printf("Arg[%d]? ", numargs);
        if ( fgets(argbuf, ARGLEN, stdin) && *argbuf != '\n' )
            arglist[numargs++] = makestring(argbuf);
        else
        {
            if ( numargs > 0 ){ 
                arglist[numargs]=NULL; 
                execute( arglist ); 
                numargs = 0; 
                }
        }
    }
    return 0;
}

execute( char *arglist[] )
{
    int pid,exitstatus;

    pid = fork(); //在这里,shell就有了自己的分身,也就是子进程(这里可以看作内存中运行了2个相同的进程)。
    switch( pid ){
        case -1:
            perror("fork failed");
            exit(1);
        case 0:
            execvp(arglist[0], arglist); //如果PID是0,说明是子进程,运行新的命令(新的shell有了新的思想)。
            perror("execvp failed");
            exit(1);
        default:
            while( wait(&exitstatus) != pid )//父进程shell等待子进程结束,并获取信息。
                ;
            printf("child exited with status %d,%d\n",
            exitstatus>>8, exitstatus&0377);
    }
}

char *makestring( char *buf )
{
    char *cp, *malloc();

    buf[strlen(buf)-1] = '\0';
    cp = malloc( strlen(buf)+1 ); 
    if ( cp == NULL ){ 
        fprintf(stderr,"no memory\n");
        exit(1);
    }
    strcpy(cp, buf); 
    return cp; 
}

刚学习fork时候,一直把父子进程看作一个程序,只是在理论上知道fork是复制了一个自己,通过上面的程序终于对fork有了一个较为清晰的认识。就好比一个懒人自己总不想做事,想要学会分身术,让分身去做事。在linux中这个懒人就是init进程,它复制了很多自己来为它做事,这些孩子们遗传了它的个性,也喜欢复制自己去做事,这就是linux系统中的一个个进程。

参考:http://blog.chinaunix.net/uid-29371197-id-4228626.html

Linux实验7】Linux Shell实现模拟多进程并发执行实验班报告 一、实验内容 二、实验过程 三、相关知识 1.shell 2.多进程并发执行 3.后台执行 4.分时系统 5.批处理 6.执行时间 7.系统态时间 8.用户态时间 阅读详情

相关推荐

Linux : 实现一个简易的 shell( mini_shell

Shell介绍: Linux系统提供给用户的最重要的系统程序是Shell命令语言解释程序。它不属于内核部分,而是在核心之外,是操作系统的外壳程序,以用户态方式运行。其基本功能是解释并执行用户打入的各种命令,实现用户Linux核心的接口。系统初启后,核心为每个终端用户建立一个进程去执行Shell解释程序。 从技术角度,Shel的最简单定义:命令行解释器(command Interpreter...

TheWindRisesll的博客 1425

shell脚本实现多进程运行的方法示例

本文主要跟大家分享了shell脚本实现多进程运行的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍: 例子 for ip in 192.168.56.{1..254} do ( ping $ip -c 4 &>/dev/null; if [ $? -eq 0 ]; then echo $ip is alive fi ) & done wait 解释 重点是在于()和&,把for里面需要执行的命令当作一个组合并在后台运行。 wait等待所有后台子程序执行完毕 执行效率 使用time可以查看运行的时间。这个效率我就不用多说了吧。 time bash a.sh 192.168.56.1

使用Shell控制多个进程并发执行

需要注意的是,由于并发执行多个进程可能涉及到资源竞争等问题,因此在实际应用中需要仔细考虑并发执行的安全性和正确性。特别是如果多个进程之间有依赖关系或者需要共享资源,可能需要使用额外的同步机制来确保正确的执行顺序和数据一致性。在Shell脚本中,我们可以通过一些方法来实现控制多个进程的并发执行。符号将命令放入后台执行,我们可以实现控制多个进程的并发执行。然而,在实际应用中需要注意并发执行的安全性和正确性,以确保程序的可靠性。在上面的示例中,我们首先定义了一个包含要执行的命令的列表。的方式将命令放入后台执行。

TechO_O的博客 1353

Linux shell实现多进程进程池)

linux shell 实现多进程

RedPomelo的博客 8285

Linux tips: shell中启动多进程并行批处理的技巧

当然,每个子进程中仍然可以包含多个串行执行的程序,建议加括号()把这些串行执行的不同的程序放到一起,表示开启子shell作为一个独立的子进程运行。最naive的方式是在shell脚本中,逐行列出需要执行的仿真命令,然后执行shell脚本。但是这样得到的效果是串行地执行shell脚本中的各条仿真命令,执行完一个再执行下一个。“&”的作用就是将计算任务转为后台执行,然后启动新的进程执行接下来的任务。这样就不用等前面的任务执行完再执行后面的任务了,从而实现了并行执行的目的。有没有更高效的做法呢?

chenxy_bwave的专栏 4887

LINUX进程

1、LINUX进程进程是一个程序一次执行的过程,是操作系统动态执行的基本单元。进程的概念主要有两点:第一,进程是一个实体。每个进程都有自己的虚拟地址空间,包括文本区、数据区、和堆栈区。文本区域存储处理器执行的代码;数据区存储变量和动态分配的内存;堆栈区存储着活动进程调用的指令和本地变量。第二,进程是一个“执行中的程序”, 它和程序有本质区别。程序是静态的,它是一些保存在磁盘上的指令的有序集合;而进程是一个动态的概念,它是一个运行着的程序,包含了进程的动态创建、调度和消亡的过程,是 Linux 的基本调度

君临 1584

进程程序替换和shell模拟实现

1.进程程序替换 1.进程程序替换概念 2.为什么要进程程序替换 3.进程程序替换原理 4.进程程序替换使用 5.调用自己并使用自己的环境变量 2.简单实现myshell 1.实现显示提示符和获取用户输入 2.字符串切分 3.创建进程执行 4.实现export

li1829146612的博客 272

shell命令以及运行原理(详解)

shell命令以及运行原理(详解)

向未来❀去探索 的博客 2255

Shell学习(一):理解Shell

大多数Linux发行版本的默认shell都是GNU bash shell。 除了我们平时登录使用的shell,系统中还有一个默认的shellsh,它用于那些需要在启动时使用的系统shell脚本 shell的父子关系 用于登录某个虚拟控制器终端或在GUI中终端仿真器中启动默认的交互的shell,是一个父shell。 在CLI提示符(命令行提示符)后输入其他的bash命令,如/bin/bashsh等,会创建一个新的shell程序,这个shell程序被称为子shell(child shell)。 一个ba

漂亮姐姐的博客 420

Linux->进程程序替换

通过我们之前对于子进程的应用,我相信大家一定是能够想到创建进程的目的之一就是为了代劳父进程执行父进程的部分代码,也就是说本质上来说父子进程都是执行的同一个代码段的数据,在子进程修改数据的时候进行写时拷贝修改数据段的部分数据。但是还有一个目的大家知道吗?不知道没关系,因为这就是本篇文章的主题,将子进程在运行时指向一个全新的程序代码,也就是我们的进程程序替换。

weixin_52345097的博客 1583

linux shell脚本执行命令创建进程问题(特定的情况,例如后台运行、管道、分支或子shell等,脚本可能会创建进程执行命令)grep

但是,当遇到特定的情况,例如后台运行、管道、分支或子shell等,脚本可能会创建进程。我说怎么在执行ps -ef | grep的过程中去grep脚本名,就会多一个进程。在大多数情况下,每条命令都在主进程中依次执行,不会创建进程Shell脚本在执行每个命令时,不一定会创建进程

Dontla的博客 2708

Linux进程控制 —— 进程创建 | 进程退出 | 进程等待 | 进程程序替换 | 实现简易shell

本文介绍了进程控制相关内容,包括进程创建、退出和等待机制。在进程创建部分,详细讲解了fork函数的实现原理和写时拷贝机制,分析了fork的使用场景和失败原因。进程退出部分阐述了三种退出场景及退出码意义,对比了return、exit和_exit三种退出方式的区别。进程等待部分说明了父进程通过wait/waitpid获取子进程状态的必要性,并演示了wait函数清除僵尸进程的过程。最后指出这些知识有助于理解shell的工作原理,为后续实现简易shell打下基础。

浮光掠影 4036

Linux系统】进程控制,实现一个简易shell

数据在默认不修改的情况下是共享的,不各自拷贝一份是因为**父子进程间的数据大部分是重复的**,一般只有少量数据需要修改,因为各自拷贝一份浪费空间。 更新父进程页表项为只读---子进程继承---子进程写入---触发系统错误---系统触发缺页中断---系统检测---判定是否要写时拷贝---拷贝,修改,恢复权限。

小羊的博客 3686

LinuxLinux进程控制 --- 进程创建、终止、等待、替换、shell派生子进程的理解…

进程等待给僵尸进程收尸,轮询等待,阻塞和非阻塞等待,7个exec替换函数,shell派生子进程的程序替换,shell的内建命令,cwd和exe路径……

The porters of knowledge 2541

LINUX shell进程创建

一、在LINUX系统中需要用到shell来运行命令。那么shell到底是什么?        维基百科:Unix shell也叫做命令行界面,它是Unix操作系统下传统的用户和计算机的交互界面。用户直接输入命令来执行各种各样的任务。         当然现在的shell不止这些功能,不同版本的shell在实现功能上也会有所差别,因为本文无关,这里不再一一赘述。 二、shell如何运行命令

咣当一生 4092

Linux进程控制 (万字详解)—— 进程创建 | 进程退出 | 进程等待 | 程序替换 | 实现简易shell

真的不点进来看看吗?Linux进程控制全新版本出炉,在图书馆用时4天呕心沥血写完,回宿舍洗澡咯

qq_42996461的博客 3020

Linux】手把手教你制作一个简易shell——(进程创建fork进程替换wait进程等待exec的应用)(自定义shell程序设计)

一.前置知识【1】Shell和Bash简述【2】Bash的输入原理——指针数组二.自定义shell程序设计【1】——大体框架【2】模块【3】模块【4】模块

YYDsis的博客 1365

Linux——进程控制&&模拟shell

我们在之前的文章中介绍过进程创建的方法,可以通过系统调用接口fork来创建新的进程。 fork在创建完新的子进程之后,返回值是一个pid,对于父进程返回子进程的pid,对于子进程返回0。fork函数后父子进程共享代码,即二者执行的是同一份代码。不同的是对于数据二者相互独立各有一份,于是对于父进程的数据修改不会影响到子进程(在修改时进行写时拷贝将父子数据独立起来)。在fork函数内,进程已经被创建进程之间相互独立,各自返回各自的返回值(父进程返回子进程PID,子进程返回0)并向下继续执行代码。

XLZ_44847的博客 1069

LInux进程程序替换shell实现:从fork到exec的完整闭环

本文深入讲解了Linux进程程序替换技术及其在shell实现中的应用。主要内容包括: 进程程序替换的必要性:fork创建的子进程只能执行父进程代码副本,而exec系列函数允许加载全新程序。 替换原理:详细分析了exec前后进程地址空间的变化,包括代码段、数据段等内存区域的替换过程。 exec函数族详解:介绍了6个exec函数的命名规律和使用场景,包括参数传递方式、PATH搜索和环境变量设置等特性。 实际应用示例:通过代码演示了execl和execlp的基本使用方法,展示了如何将当前进程替换为其他程序。 技术

半截诗的博客~ 1230
上一篇: linux C语言fork进程学习
下一篇: 多源传感器融合时的时间对齐或者时间同步问题
土豆西瓜大芝麻
博客等级 码龄18年 1146粉丝 238原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值