linux执行ls会引起什么系统调用
这篇文章给大家分享的是有关linux执行ls会引起什么系统调用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。在linux中,执行ls会引起read和exec系统调用;执行任何一个shell命令都会调用fork和exec,但是通过strace去查看ls引起的系统调用并没有fork,ls命令要列出目录下的文件,所以要调用read。本教程操作环境:linux7.3系统、Dell G3电脑。答案是read、exec系列
shell命令执行机制就是 fork+exec, fork是分身,execve是变身。ls命令要列出目录下的文件,所以read也会调用。shell访问Linux内核就是通过fork和exec命令实现的,fork命令创建可以一个相同的线程出来。通过strace去查看ls引起的系统调用,确实是没有fork,但是因为执行任何一个shell命令都会调用forkexecve的变身就是创建一个新的进程,并用新的进程去替换掉原来的进程。首先我们讨论一下什么是系统调用(system calls)?
用户借助UNIX/linux直接提供的少量函数可以对文件和设备进行访问和控制,这些函数就是
系统调用
[1]。使用
strace ls
命令我们可以查看ls命令使用到的系统调用[2],其中一部分输出内容如下:open系统调用打开当前目录文件,返回获得的文件描述符。可以看到该文件使用O_RDONLY标志打开。只要该文件是用O_RDONLY或O_RDWR标志打开的,就可以用
read()
系统调用从该文件中读取字节[3]。所以
ls
要用到
read
系统调用。除此之外,任何shell命令都会创建进程,都会用到exec系统调用。回过头来梳理一下我们对于这些概念可能产生的疑惑:包括ls在内,一个程序是如何运行的?open系统调用打开当前目录文件,返回获得的文件描述符。那什么是文件描述符?每个运行中的程序被称为进程[1]Unix将进程创建与加载一个新进程映象分离。这样的好处是有更多的余地对两种操作进行管理。当我们创建了一个进程之后,通常将子进程替换成新的进程映象。所以任何shell命令都会创建进程,都会用到exec系统调用。
例如:在shell命令行执行ps命令,实际上是shell进程调用fork复制一个新的子进程,在利用exec系统调用将新产生的子进程完全替换成ps进程。用exec函数可以把当前进程替换为一个新进程,且新进程与原进程有相同的PID。exec名下是由多个关联函数组成的一个完整系列[4]调用fork创建新进程后,父进程与子进程几乎一模一样[1,p398]。fork是一个UNIX术语,当fork一个进程(一个运行中的程序)时,基本上是复制了它,并且fork后的两个进程都从当前执行点继续运行,并且每个进程都有自己的内存副本。原进程是父进程,新进程是子进程。可以通过
fork()
返回值区分。
父进程中fork调用返回的是新的子进程的pid(process id),而子进程中fo开发云主机域名rk调用返回的是0
举个例子:如果想要程序启动另一程序的执行但自己仍想继续运行的话,怎么办呢?那就是结合fork与exec的使用[6][1, p397]举个例子(修改自[6]):先fork,然后子进程借助exec调用程序command。对错误命令、需要参数的命令、以及不需要参数的命令给出对应的输出。一切设备都可以看作文件。对内核而言,所有打开的文件都通过文件描述符引用[7]。文件描述符是非负整数,范围是[0,OPEN_MAX -1]。现在OPEN_MAX 一般为64但是[7]又说对于FreeBSD 8.0,Linux 3.2.0 ,Mac OS X 10.6.8等, fd变化范围几乎无限,只受到存储器数量、int字长以及系统管理员所配置的软限制和硬限制的约束。。。why?当open或者create一个新文件时,内核向进程返回一个文件描述符。当读、写一个文件时,使用open或create返回的文件描述符标识该文件,将其作为参数传送给
read / write
按照惯例,fd为0 / 1 / 2分别关联STDIN_FILENO / STDOUT_FILENO / STDERR_FILENO。这些常量也定义在
unistd.h
.包括exec、fork、read、write在内,许多系统调用包含在
unistd.h
头文件中POSIX,Portable Operating System Interface。是UNIX系统的一个设计标准,很多类UNIX系统也在支持兼容这个标准,如Linux。
unistd.h
是POSIX标准定义的unix类系统定义符号常量的头文件,包含了许多UNIX系统服务的函数原型[5]。在该头文件,用于访问设备驱动程序的底层函数(系统调用)有这五个:
open/close/read/write/ioctl
[1]。[7]中提到大多数文件I/O用到的5个函数为:
open/read/write/lseek/close
调用read函数从打开文件中读数据。返回值开发云主机域名:成功,读出的字节数;失败,-1;遇到文件尾,0有多种情况可使实际读到的字节数少于要求读的字节数:读普通文件时,在读到要求字节数之前已经到达了文件尾端。例如,若在到达文件尾端之前还有30个字节,而要求读100个字节,则read返回30,下一次再调用read时,它将回0。当从终端设备读时,通常一次最多读一行当从网络读时,网络中的缓冲机构可能造成返回值小于所要求读的字节数。当从管道或FIFO读时,如若管道包含的字节少于所需的数量,那么read将只返回实际可用的字节数。当从某些面向记录的设备(例如磁盘)读时,一次最多返回一个记开发云主机域名录。当某一信号造成中断,而已经读了部分数据量时。读操作从文件的当前偏移量出开始,在成功返回之前,该偏移量将增加实际独到的字节数read的经典原型定义则是:
int read(int fd, char*buf, unsigned nbytes);
感谢各位的阅读!关于“linux执行ls会引起什么系统调用”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!
本文从转载,原作者保留一切权利,若侵权请联系删除。
《linux执行ls会引起什么系统调用》来自互联网同行内容,若有侵权,请联系我们删除!