Rumah > Operasi dan penyelenggaraan > operasi dan penyelenggaraan linux > Apakah panggilan sistem yang akan disebabkan oleh melaksanakan ls dalam Linux?

Apakah panggilan sistem yang akan disebabkan oleh melaksanakan ls dalam Linux?

WBOY
Lepaskan: 2022-03-18 11:05:00
asal
4062 orang telah melayarinya

Di Linux, melaksanakan ls akan menyebabkan panggilan sistem baca dan eksekusi; melaksanakan sebarang perintah shell akan memanggil fork dan exec, tetapi jika anda menggunakan strace untuk menyemak panggilan sistem yang disebabkan oleh ls, tiada fork arahan mesti disenaraikan Fail dalam direktori, jadi baca mesti dipanggil.

Apakah panggilan sistem yang akan disebabkan oleh melaksanakan ls dalam Linux?

Persekitaran pengendalian tutorial ini: sistem linux7.3, komputer Dell G3.

Apakah panggilan sistem yang akan disebabkan oleh melaksanakan ls dalam Linux

Jawapannya adalah siri baca dan laksanakan

The mekanisme pelaksanaan perintah shell ialah fork exec, fork ialah klon, dan execve ialah transformasi. Perintah ls menyenaraikan fail dalam direktori, jadi baca juga akan dipanggil.

Akses shell kepada kernel Linux dicapai melalui perintah fork dan exec Perintah fork boleh mencipta benang yang sama.

Gunakan strace untuk menyemak panggilan sistem yang disebabkan oleh ls Memang benar tiada fork, tetapi kerana melaksanakan mana-mana arahan shell akan memanggil fork

eksekusi Transformasi adalah untuk mencipta proses baharu dan menggantikan proses asal dengan proses baharu.

Pertama sekali, mari kita bincangkan apakah panggilan sistem?
Pengguna boleh mengakses dan mengawal fail dan peranti dengan bantuan sebilangan kecil fungsi yang disediakan secara langsung oleh UNIX/linux Fungsi-fungsi ini adalah 系统调用[1].

Menggunakan perintah strace ls kita boleh melihat panggilan sistem yang digunakan oleh arahan ls [2], sebahagian daripada output adalah seperti berikut:

open(".", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 3
getdents64(3, /* 68 entries */, 32768)  = 2240
getdents64(3, /* 0 entries */, 32768)   = 0
close(3)                                = 0
Salin selepas log masuk

panggilan sistem terbuka membuka arus fail direktori dan mengembalikan deskriptor fail yang diperolehi. Anda boleh melihat bahawa fail dibuka dengan bendera O_RDONLY.

Selagi fail dibuka dengan bendera O_RDONLY atau O_RDWR, bait boleh dibaca daripada fail menggunakan panggilan sistem read() [3].

Jadi ls perlu menggunakan read panggilan sistem. Di samping itu, sebarang arahan shell yang mencipta proses akan menggunakan panggilan sistem exec.

Mari kita kembali dan selesaikan keraguan yang mungkin ada pada konsep ini:

  1. Bagaimanakah program berjalan, termasuk ls?
  2. Panggilan sistem terbuka membuka fail dalam direktori semasa dan mengembalikan deskriptor fail yang diperolehi. Jadi apakah deskriptor fail?

1 Cara proses berjalan

Setiap atur cara berjalan dipanggil proses [1]

Unix mencipta dan memuatkan imej proses baharu Pemisahan imej. Kelebihan ini ialah terdapat lebih banyak kelonggaran untuk menguruskan kedua-dua operasi. Selepas kami membuat proses, kami biasanya menggantikan proses anak dengan imej proses baharu. Jadi sebarang arahan shell akan mencipta proses dan menggunakan panggilan sistem exec.
Contohnya: apabila melaksanakan perintah ps pada baris arahan shell, proses shell sebenarnya memanggil fork untuk menyalin proses anak baharu, dan kemudian menggunakan panggilan sistem exec untuk menggantikan sepenuhnya proses anak yang baru dijana dengan proses ps.

Gunakan fungsi exec untuk menggantikan proses semasa dengan proses baharu, dan proses baharu mempunyai PID yang sama seperti proses asal. Di bawah nama exec ialah siri lengkap yang terdiri daripada berbilang fungsi yang berkaitan [4]

Selepas memanggil fork untuk mencipta proses baharu, proses induk dan proses anak adalah hampir sama [1, p398].

Fork ialah istilah UNIX Apabila proses (program berjalan) dicabang, ia pada asasnya disalin, dan kedua-dua proses selepas garpu terus berjalan dari titik pelaksanaan semasa, dan setiap Setiap proses mempunyai sendiri. salinan ingatan.

Proses asal ialah proses induk, dan proses baharu ialah proses anak. Boleh dibezakan dengan fork() nilai pulangan.

Panggilan fork dalam proses induk mengembalikan pid (id proses) proses anak baharu, manakala panggilan fork dalam proses anak mengembalikan 0

Sebagai contoh :

#include<unistd.h>
#include<stdio.h>
#define LEN 10
int main()
{
    pid_t id=getpid();
    printf("Main pid: %d \n",id);
	int i;
	pid_t res=fork();
	if(res==0)
	{
	  for(i =0;i<LEN;i++) 
	  {
		pid_t id1=getpid();
		printf("%d ",id1);
		printf("Child process:%d\n",i);
	  }
	}
	else
	{
	  printf("res %d\n",res);
	  for(i=0;i<LEN;i++) 
	  {
		pid_t  id2=getpid();
		printf("%d ",id2);
		printf("parent process:%d\n",i);
	  }
	}

	printf("THE END\n");
	 return 0;
}

/*output
Main pid: 10965 
res 10966
10965 parent process:0
10965 parent process:1
10965 parent process:2
10965 parent process:3
10965 parent process:4
10965 parent process:5
10965 parent process:6
10965 parent process:7
10965 parent process:8
10965 parent process:9
10966 Child process:0
10966 Child process:1
THE END
10966 Child process:2
10966 Child process:3
10966 Child process:4
10966 Child process:5
10966 Child process:6
10966 Child process:7
10966 Child process:8
10966 Child process:9
THE END
*/
Salin selepas log masuk

Apakah yang perlu anda lakukan jika anda mahu program memulakan pelaksanaan program lain tetapi anda masih mahu meneruskannya? Iaitu untuk menggabungkan fork dan exec [6][1, p397]

Sebagai contoh (diubah suai daripada [6]):

#include<string.h>
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
#include<unistd.h>
 
 char command[256];
 void main()
 {
    int rtn; /*子进程的返回数值*/
    while(1) {
       /* 从终端读取要执行的命令 */
       printf( ">" );
       fgets( command, 256, stdin );
       command[strlen(command)-1] = 0;
       if ( fork() == 0 ) {/* 子进程执行此命令 */
          execlp( command, NULL );
          /* 如果exec函数返回,表明没有正常执行命令,打印错误信息*/
          perror( command );
          exit( errno );
       }
       else {/* 父进程, 等待子进程结束,并打印子进程的返回值 */
          pid_t sonid=wait ( &rtn );
          printf(" child pid: %d\n",sonid);
          printf( " child process return %d\n", rtn );
       }
   }
}

/*output:错误命令、需要参数命令、正确命令
>aa
aa: No such file or directory
 child pid: 11230
 child process return 512
>echo
A NULL argv[0] was passed through an exec system call.
 child pid: 11231
 child process return 134
>ps
 child pid: 11247
 child process return 139
*/
Salin selepas log masuk

Fork dahulu, dan kemudian proses anak menggunakan exec Panggil arahan program. Sediakan output yang sepadan untuk arahan ralat, arahan yang memerlukan parameter dan arahan yang tidak memerlukan parameter.

2 Deskriptor fail (fd)

Semua peranti boleh dianggap sebagai fail.

对内核而言,所有打开的文件都通过文件描述符引用[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.

3 系统调用包含在哪些头文件中呢?

包括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]。

4 文件I/O

[7]中提到大多数文件I/O用到的5个函数为:open/read/write/lseek/close

4.1 函数read

调用read函数从打开文件中读数据。

#include<unistd.h>
ssize_t read(int filedes, void *buf, size_t nbytes);
Salin selepas log masuk

返回值:

成功,读出的字节数;

失败,-1;

遇到文件尾,0

有多种情况可使实际读到的字节数少于要求读的字节数:

  • 读普通文件时,在读到要求字节数之前已经到达了文件尾端。

例如,若在到达文件尾端之前还有30个字节,而要求读100个字节,则read返回30,下一次再调用read时,它将回0。

  • 当从终端设备读时,通常一次最多读一行

  • 当从网络读时,网络中的缓冲机构可能造成返回值小于所要求读的字节数。

  • 当从管道或FIFO读时,如若管道包含的字节少于所需的数量,那么read将只返回实际可用的字节数。

  • 当从某些面向记录的设备(例如磁盘)读时,一次最多返回一个记录。

  • 当某一信号造成中断,而已经读了部分数据量时。读操作从文件的当前偏移量出开始,在成功返回之前,该偏移量将增加实际独到的字节数

read的经典原型定义则是:

int read(int fd, char*buf, unsigned nbytes);

相关推荐:《Linux视频教程

Atas ialah kandungan terperinci Apakah panggilan sistem yang akan disebabkan oleh melaksanakan ls dalam Linux?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan