We came across ls in a previous article when we explained “ What happens when you type ls *.c”. However in this article we’re going to explain what really happens when you type ls- l.
我们在前面的文章中碰到LS当我们解释说,“ 当你输入ls会发生什么的* .c” 。 但是,在本文中,我们将解释当您键入ls-l时实际发生的情况。
ls
is a Unix-related systems command that lists the contents of a directory. The -l
on the other hand is known as an option or flag. We can find multiple options for ls
, too many to list in fact, however the l
in particular will allow ls
to list the contents of a directory in “long format”. Whereas “normal format” will only list the names of each file and sub-directory, “long format” will write each file name on its own line, as well as include additional info such as owner’s name, permission settings, a date for when it was last modified and the size of the content
ls
是与Unix相关的系统命令, 列出了目录的内容。 另一方面, -l
被称为选项或标志。 我们可以找到ls
多个选项,实际上没有太多列出,但是l
尤其允许ls
以“长格式”列出目录的内容。 “普通格式”将仅列出每个文件和子目录的名称,“长格式”将在每个文件行上写入每个文件名,并包括其他信息,例如所有者的名称,权限设置,日期等上次修改的时间和内容的大小
1. This is what you first see when you open the terminal:
1.这是打开终端时首先看到的内容:
2. Go ahead and type the commandls -l
:
2.继续并输入命令ls -l
:
![Image for post](https://miro.medium.com/max/9999/1*IQB_cN0BGeHMxwVpHqLrbA.jpeg)
3. you’ll end up with something like this when pressing ENTER:
3.按下ENTER键,您将得到如下所示的结果:
![Image for post](https://miro.medium.com/max/9999/1*72XgYGdLYiO__g3eUGoN_A.jpeg)
那么,当您在shell中键入“ ls -l”时,会发生什么呢? (So what really happens when you type “ls -l” in the shell?)
the result of shell using getline()
to take from standard input and write the resulting character string to a variable of type char *
is what appears to be a prompt for user input. This character string needs to be split into its components, i.e., a command plus its options and arguments.
Shell使用getline()
从标准输入中提取结果并将字符串写入char *
类型的变量的结果似乎提示用户输入。 该字符串需要拆分成各个部分,即命令加上其选项和参数。
Before I discuss tokenizing or splitting what was entered into getline()
, allow me to take a detour. If getline()
does not fail, shell will create a child process for its current process using fork()
. Built-ins only need a fork to be executed. Otherwise, if the PATH
is searched through , a function execve()
will be then called to execute the external command. Let’s get back to our single string of command + options + arguments.
在讨论标记化或拆分输入到getline()
, getline()
绕行。 如果getline()
没有失败,则shell将使用fork()
为其当前进程创建一个子进程。 内置插件仅需要执行fork。 否则,如果通过PATH
搜索,则将调用函数execve()
来执行外部命令。 让我们回到命令+选项+参数的单个字符串。
In the case of (ls -l
) a tokenizer function will divide the character string into two parts based on the fact of the separation of the components with a space. This is known as parsing or tokenizing.
在( ls -l
)的情况下,基于组成部分之间用空格分隔的事实,令牌化程序功能会将字符串分为两部分。 这称为解析或标记化。
expansion could be ignored with special characters like bracket, `$
`, and the asterisk (`*
`). the expansion will usually occur after tokenization however before the command is searched for.
扩展名可以用括号,` $
`和星号(` *
`)等特殊字符忽略。 扩展通常会在标记化之后但在搜索命令之前发生。
Now that we separated the command from its option, we’re able to begin the search for the command, and the first place to do that is a file in the home directory whose path is ~/.bashrc
. If alias is not found, the command would be compared to the list of built-ins.
现在我们将命令与其选项分开了,我们可以开始搜索该命令了,首先要做的是主目录中的文件,其路径为~/.bashrc
。 如果找不到别名 ,则将命令与内置列表进行比较。
![Image for post](https://miro.medium.com/max/9999/1*SKdZDWDatHZdce4NNG1FRA.png)
Built-ins are usually defined when the shell starts and undefined when it ends since they’re stored in memory allocated for the shell . Different shells store built-ins differently. Because they’re are built in the shell itself they’re much faster to load than if they were defined in an external file. In a project that this writer contributed to, built-ins were listed in a structure from which a function pointer could select the proper built-in function to execute.
内置程序通常在外壳程序启动时定义,而在外壳程序结束时则未定义,因为它们存储在为外壳程序分配的内存中。 不同的外壳以不同的方式存储内置组件。 因为它们是内置在shell本身中,所以它们的加载速度比在外部文件中定义的要快得多。 在作者撰写的一个项目中,内置结构被列出在一个结构中,函数指针可以从该结构中选择适当的内置函数来执行。
Finally, when the command is not found in the list of built-ins, the shell will search a single string of different directories separated by colons called the environment variable PATh
. First it’ll be tokenized into its component directories then concatenated with a /ls
to create a bunch of hypothetical paths that enables the determination if these hypothetical paths exist by having the shell call a function stat()
. This function will make a comparison of these hypothetical paths with the actual paths, and if ls actually exists in one of them, stat
will return data that the command was found.
最后,当在内置列表中找不到该命令时,shell将搜索由冒号分隔的不同目录的单个字符串,称为环境变量PATh
。 首先,将其令牌化到其组件目录中,然后与/ls
连接以创建一堆假设路径,这些路径通过让外壳程序调用stat()
函数来确定这些假设路径是否存在。 此函数将这些假设路径与实际路径进行比较,如果ls实际上存在于其中一个路径中,则stat
将返回找到该命令的数据。
the shell will return an error If the command cannot be found in .bashrc
, the list of built-ins, or in PATH
.
如果无法在.bashrc
,内置列表或PATH
找到该命令,则Shell将返回错误。
A list of options will be present in that command’s source code wherever the command is found . The list will take the form of switch statements or a structure. and this is where you will find the -l
无论在何处找到该命令,选项的列表都会出现在该命令的源代码中。 该列表将采用switch语句或结构的形式。 在这里您会找到-l
so this is what actually happens when we type ls -l
into our shell.
因此,这就是在我们的shell中键入ls -l
时实际发生的情况。
翻译自: https://medium.com/@onsjannet/what-happens-when-you-type-ls-l-in-the-shell-281b832e625