shell ls -l_在shell中键入ls l会发生什么

shell ls -l

Since we are going to review the process from the very beginning, it’s really important that we see some concepts before getting into the real matter.

由于我们将从一开始就对流程进行审查,因此在进入实质问题之前先了解一些概念非常重要。

Image for post

什么是“壳牌”? (What is “the Shell”?)

It is a program that takes commands from the keyboard and gives them to the operating system to perform. On most Linux systems a program called bash (which stands for Bourne Again Shell, written by Steve Bourne) acts as the shell program, but of course, this is only one of the several options we have.

它是一个程序,可从键盘获取命令并将其交给操作系统来执行。 在大多数Linux系统上,称为bash的程序(由Steve Bourne代表Bourne Again Shell,由Steve Bourne编写)充当shell程序,但是,当然,这只是我们拥有的几种选择之一。

什么是“终端”? (What’s a “Terminal?”)

Or terminal emulator, it’s a program that opens a window and enables a machine to connect to and communicate with another machine using a command line or graphical interface (the Shell). There are a bunch of different terminal emulators you can use.

终端仿真器,它是一个程序,它将打开一个窗口,并使一台计算机可以使用命令行或图形界面(命令行管理程序)连接到另一台计算机并与之通信。 您可以使用许多不同的终端模拟器。

什么是“命令”? (What are “commands”?)

In computing, a command is a directive to a computer program sent by the user to perform a specific task. In simple words, they tell the computing device what to do or execute next, depending on the command sent.

在计算中, 命令是用户发送的执行特定任务的计算机程序指令。 简而言之,它们根据发送的命令告诉计算设备下一步做什么或执行什么。

这是一些最常见的图表: (This is a chart with some of the most common ones:)

Image for post

Many programs allow specially formatted arguments, known as flags or options, which modify the default behavior of the program, while further arguments may provide objects, such as files, to act on. Comparing to a natural language: the flags are adverbs, while the other arguments are objects.

许多程序允许使用特殊格式的参数(称为标志或选项)来修改程序的默认行为,而其他参数可能会提供对象(例如文件)来执行操作。 与自然语言相比:标志是副词,其他参数是对象。

Now that we know the basics, we can continue to review our main question:

现在我们已经了解了基础知识,我们可以继续审查我们的主要问题:

当我们在shell中键入ls -l时,实际上会发生什么? (What actually happens when we type ls -l in our shell?)

First of all, ls is a command that lists information given to it via standard input about the files (on the current directory by default) and writes the results in alphabetical order to standard output. It can take several arguments such as -a ( do not ignore entries starting with ‘.’), -r (reverse order while sorting),-s (print the allocated size of each file, in blocks), and so on… but our key flag today is typing ls -l, so here is an example of what we get when we do:

首先, ls是一个命令,该命令列出通过标准输入提供的有关文件的信息(默认情况下位于当前目录中),并将结果按字母顺序写入标准输出。 它可以使用多个参数,例如-a(不要忽略以'。'开头的条目) ,-r(排序时的反向顺序) ,-s(以块为单位打印每个文件的分配大小),等等……但是今天我们的关键标志是键入ls -l ,所以这是我们执行操作时得到的示例:

Image for post

What we know up to this point is that with “ls” we can list information, but when we add “-l”, we can see all the files and directories in the current working directory but displayed in a long format, headed with the respective permissions, the owners and users, and dates and time in which they were created.

到目前为止,我们所知道的是,使用“ ls”可以列出信息,但是当添加“ -l”时,我们可以看到当前工作目录中的所有文件和目录,但以长格式显示,以各自的权限,所有者和用户以及创建它们的日期和时间。

但是,幕后真正发生了什么? (But what does it really happen behind the scenes?)

Image for post

We have 4 main steps our shell performs to do this whole process with the commands:

我们的外壳程序执行以下四个主要步骤来使用以下命令完成整个过程:

  1. Display prompt

    显示提示
  2. Read

  3. Interpret

    口译
  4. Execute

    执行

But there are more “smaller” processes in between these 4 steps. Let’s go ahead and review each one of them:

但是在这四个步骤之间还有更多的“较小”过程。 让我们继续检查其中的每一个:

  1. Display prompt: “$” is printed to initialize a new line, and what is typed after it, is what is going to be read by getline().

    显示提示:打印“ $”以初始化新行,其后键入的内容将是getline()将读取的内容。

2. Read command with getline():

2.使用getline()读取命令

This function reads an entire line from stream, storing the address of the buffer containing the text into *lineptr. The buffer has a terminating null byte and includes the newline character if one was found. If *lineptr is NULL, then getline() will allocate a buffer for storing the line, which should be freed by the user program. Alternatively, before calling getline(), *lineptr can contain a pointer to a malloc allocated buffer *n bytes in size. If the buffer is not large enough to hold the line, getline() resizes it with realloc, updating *lineptr and *n as necessary. This is how our function’s prototype looks like:

该函数从流中读取整行,并将包含文本的缓冲区的地址存储到* lineptr中 。 该缓冲区有一个终止的空字节,并且如果找到一个则包含换行符。 如果* lineptr为NULL,则getline ()将分配用于存储行的缓冲区,该缓冲区应由用户程序释放。 另外,在调用getline ()之前, * lineptr可以包含一个指向malloc分配的缓冲区的指针* n个字节。 如果缓冲区的大小不足以容纳该行,则getline ()使用realloc调整其大小,并根据需要更新* lineptr* n 。 这就是我们的函数原型的样子:

ssize_t getline(char **lineptr, size_t *n, FILE *stream);Basically what it does, is that it waits for the user to type in any character, reads and stores it into a buffer and finally waits until you press enter or (Ctrl+D).

3. Interpret and parse a command with strtok():

3.使用strtok()解释并解析命令

Image for post

This function breaks a string into a sequence of individual tokens. On the first call to strtok(), the string to be parsed (cut) should be specified in str. In each subsequent call that should parse the same string, str must be NULL. Each call to strtok() returns a pointer to a null-terminated string containing the next token but not the delimiting byte. If no more tokens are found, strtok() returns NULL.

此函数将字符串分成单个标记序列。 首次调用strtok()时 ,应在str中指定要解析(剪切)的字符串 。 在每个随后的应解析相同字符串的调用中, str必须为NULL。 每次对strtok ()的调用都会返回一个指向以空值结尾的字符串的指针,该字符串包含下一个标记,但不包含分隔字节。 如果找不到更多令牌,则strtok ()返回NULL。

Validation process

验证程序

On this step, we got 3 conditionals we need to verify if true, that are (1) if there are any aliases or special characters, and(2) if it’s a builtin command.- Aliases: refers to the situation where the same memory location can be accessed using different names. So after the two previous steps are done, the Shell will check for any alias that matches what the user meant in the command type and what it has internally stored. If any alias is found, it will expand that alias before executing the command.-Special characters: after the previous process gets done, it will then search for special characters like: “,‘, \, *, &, :, #” and execute the logic associated with the special character. -Builtin commands: finally it checks if the buffer has entered built-in commands( is a command or function that is part of the shell itself). Some of them are break, cd, echo, exit, help, pwd, read, and so on…

在这一步上,我们需要3个条件来验证是否为true,即(1)是否有任何别名或特殊字符,以及(2)如果是内置命令。-别名:指相同内存的情况可以使用其他名称访问该位置。 因此,在完成前面的两个步骤之后,命令行管理程序将检查是否有任何别名与用户在命令类型中所指的内容以及其在内部存储的内容相匹配。 如果找到任何别名,它将在执行命令之前扩展该别名。-特殊字符:完成上一过程后,它将搜索特殊字符,例如: “,',\,*,&,:,#”并执行与特殊字符关联的逻辑。 -内置命令:最后,它检查缓冲区是否输入了内置命令(是外壳本身的一部分的命令或函数)。 其中一些是break,cd,echo,exit,help,pwd,read等,等等。

PATH process

路径过程

PATH is an environment variable in Linux and other Unix-like operating systems that tells the shell which specific directories to search for executable files in response to commands issued by the user. What the Shell does with this is that it searches for ls in the PATH variable to make sure it’s not a builtin command, so it then copies the environment and passes it to the new process to modify the path. Although this variable is a list of directories that the shell searches for every time a command is entered, once identified the path or its content, they will be parsed (cut) into smaller parts every time the delimiter “:” used to separate them is found.

PATH是Linux和其他类似Unix的操作系统中的环境变量,它告诉Shell响应于用户发出的命令,哪个特定目录搜索可执行文件。 Shell这样做的原因是,它在PATH变量中搜索ls以确保它不是内置命令,因此它将复制环境并将其传递给新进程以修改路径。 尽管此变量是shell每次输入命令时都会搜索的目录的列表,但一旦标识了路径或其内容,则每当使用分隔符“:”分隔时,它们都会被解析(剪切)成较小的部分。找到了。

Fork() and execve()

Fork()和execve()

The first function fork() creates a new process by duplicating the calling one. The new process is referred to as the child process and the calling process is referred to as the parent process using this form: pid_t fork(void);

第一个函数fork()通过复制调用者来创建一个新进程。 新进程称为进程,调用进程称为进程,其格式如下: pid_t fork(void);

The second function execve() executes the program pointed to by filename, which much be either a binary executable or a script starting with a line of the form: #! interpreter [optional-arg]

第二个函数execve()执行文件名指向的程序文件可以是二进制可执行文件,也可以是以以下格式的行开头的脚本: #! 解释器[optional-arg]

Image for post

If the file exists: forking and execution are done in the program of the child process. When executing it, three system calls (which provide an essential interface between a process and the operating system) will be seen by “fork”, a system call that creates a clone of the current process copying data such as the environment among others, and passing it to the new process, “execve” that executes the program that is referred to by the pathname and “wait” that suspends the execution of the current process until one of its children finishes.

如果文件存在:分叉和执行在子进程的程序中完成。 执行它时,三个系统调用 (在进程和操作系统之间提供基本接口) 将被“ fork”看到,这是一个系统调用,它创建当前进程的副本,以复制诸如环境之类的数据,并将其传递给新进程“ execve” ,该进程执行路径名所引用的程序和“等待” 它会暂停当前进程的执行,直到其子进程之一完成为止。

So, once the fork requirements are met, exceve is called to stop the duplication of the parent process, runs the command and loads ls, (or the new process in this case), replacing parts of the current process. Then wait is called so the parent process waits for the child to finish its regular course while the parent process continues to do other things and keeping track of the children at the same time. Now when it finally reaches the Shell system again, to exit depending on the result or status in which the parent is at. And finally, after a child process terminates, the parent process will print the prompt to the user.

因此,一旦满足fork的需求, 就会调用exceve来停止父进程的复制,运行命令并加载ls(在这种情况下为新进程),从而替换当前进程的一部分。 然后调用wait ,以便父进程等待子进程完成其常规课程,而父进程继续执行其他操作并同时跟踪子进程。 现在,当它最终再次到达Shell系统时,要根据父项所在的结果或状态退出。 最后,子进程终止后,父进程将向用户打印提示。

4. The command typed in the first place is executed and if error, it will print the message specified according to the situation:

4.首先执行键入的命令,如果出错,则将根据情况打印指定的消息:

  • If success, (ls -l), the correct execution of the command is shown.

    如果成功(ls -l),则显示命令的正确执行。
  • If we type something the Shell wouldn’t recognize like (hola), it would

    如果我们输入Shell无法识别的东西,例如(hola),它将

    print “hola: not found”.

    打印“ hola:未找到”。

  • If we misspell something like (ls l), it will display “ls: cannot access l: No such file or directory”.

    如果我们拼错了(ls l)之类的内容,它将显示“ ls:无法访问l:没有此类文件或目录”。

And once this is done, it will print the prompt again to the user again.

完成后,它将再次将提示打印给用户。

Made by:

由制成:

  • Francisco Guzmán

    弗朗西斯科·古兹曼
  • Silena Restrepo

    西琳娜·雷斯特雷波(Silena Restrepo)
  • Lilibeth Tabares

    利比里斯塔巴雷斯

翻译自: https://medium.com/@silenarestrepo/what-happens-when-you-type-ls-l-in-the-shell-322af6b6356b

shell ls -l

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值