为什么 Linux 中需要 shell?例如,当我输入时,系统find . -name xy\*
会告诉我 shell 会接受此输入并调用 find 命令(确保通配符被正确解释等等)。如果没有 shell 的概念,难道这还做不到吗……?如果 shell 跟踪各种进程,难道这还做不到吗?
另外,为什么我可以输入>ls xy*
并获得正确的输出,而我需要用 in find - 退出*
?\
shellfind . -name xy\\*
是否对一个可执行文件进行通配符扩展,而对另一个可执行文件不进行?
答案1
如果没有 shell 的概念,这难道不能做到吗?
嗯,不是。你需要一个东西来解释你的意图并调用相应的程序。这个东西叫做 shell。
编辑:为避免混淆,“shell”并不意味着“命令行界面”。来自http://en.wikipedia.org/wiki/Shell_(计算):
“操作系统 shell 通常分为两类:命令行和图形。命令行 shell 为操作系统提供命令行界面 (CLI),而图形 shell 提供图形用户界面 (GUI)。无论哪种类型,shell 的主要用途都是调用或“启动”另一个程序;但是,shell 通常具有其他功能,例如查看目录内容。”
至于您的另一个问题,shell 正在对两个命令进行通配符扩展,但是当您使用 find 搜索文件时,您希望 find 而不是 shell 进行扩展,因为您希望它在 find 正在查找的位置完成,而不是在调用它的位置完成;因此,您转义 * 以阻止 shell 对其进行扩展,以便 find 可以看到它。
答案2
当然,您可以通过 GUI 完成所有操作。Windows 的“查找文件”(从 XP 及更早版本开始)在某种程度上相当于您输入的命令的 GUI。
那么,为什么 UNIX(和 Linux)用户喜欢 shell?因为您可以获取输出,将其输入到另一个程序中,并获得不同的输出。例如:
find | grep burek
这是两个命令,find
和grep
,一个命令作为另一个命令的输入。find
列出当前文件夹和所有子文件夹中的所有文件,每行一个,并且grep
仅打印出包含的行burek
。
现在,还有其他更复杂的事情,例如:
ls -R | sort | uniq
ls -R
列出当前文件夹和子文件夹中的文件,并对sort
输出进行排序。uniq
然后只给我们唯一的行。
现在,虽然您可以将所有这些代码编写到 GUI 中,但您可以使用命令行快速完成一些棘手的事情,而这些事情您通常无法使用 GUI 来完成,除非您自己编写。在这种情况下,直接将其输入命令行会更快,不是吗?
底线:如果你问这个问题,那你不需要它。命令行对于普通用户来说毫无用处。然而,命令行对于系统管理员、开发人员以及那些想要快速摆弄电脑的人来说非常有用。
答案3
是的,您可以在没有 shell 的情况下运行 find 命令 - 但您需要一些程序来启动它,并且您需要一些程序来显示它的输出。很多时候,您正在使用 shell 的功能,并且该命令将需要 shell 来解释意图。
例如,管道、重定向和通配符是 shell 的功能,需要 shell 来解释。“find . -name myfile”不使用 shell 的任何功能,可以在没有 shell 的情况下运行。“find . -name myfile | sort >output”同时使用管道和重定向,您需要一个 shell 来解释它。
至于转义 xy* ,如果它是查找的输入或重新定义的输出,则几乎没有区别,无论哪种方式,shell 都会扩展它。
如果当前目录中有一个名为 xyz 的文件
find . -name xy* 实际上将作为 find . -name xyz 运行,这可能不是您想要的。
如果您确实找到 . -name xy*,并且当前目录中没有与 xy* 匹配的文件,它将作为 find . -name xy* 运行。
类似地,如果当前目录中没有与 xy* 匹配的文件,则 ls >xy* 将创建一个名为 xy* 的文件。如果有一个文件匹配(例如 xyz),则意味着 ls >xyz。如果有多个文件与 xy* 匹配,则 ls >xy* 将失败。
答案4
回答你的第二个问题...除非你阻止,否则 shell 会尝试尽可能地扩展它能扩展的内容。转义 * 可阻止扩展,这通常是 find 命令所必需的。
不以问题来回答问题,你怎么知道 ls 命令是由于命令行扩展而列出的文件,还是因为 ls 命令合法地从文件系统中查找了目录列表?例如,我可以编写一个这样的 shell for 循环:
for i in $(ls /home/mydir);
或者类似
for i in /home/mydir/*;
它们最终会得到相同的结果。