【问题标题】:Is linux shell just optional utility or mandatory when running processeslinux shell 只是可选实用程序还是在运行进程时是必需的
【发布时间】:2016-10-13 14:07:13
【问题描述】:

尽管我经常使用 linux,但我仍然对 linux shell 运行程序的角色感到困惑。

我知道有两种类型的 shell,交互式 shell 和非交互式 shell。终端会话与交互式 shell 交互,脚本在非交互式 shell 中运行。但是除了读取输入和打印输出的能力之外,真的有其他区别吗?如果我从 shell 调用脚本,它是在这个交互式 shell 中运行还是在 shell 内新的非交互式 shell 中运行?

另外,当我通过交互式 shell 或图形界面调用二进制文件时,它是否总是在 shell 中运行,或者进程可以在没有 shell 的情况下运行?据说所有进程都通过 shell 与内核通信,但我很困惑,因为在 docker 中,您可以将入口点定义为二进制文件或“sh -c 二进制文件”。

【问题讨论】:

  • shell 是一个命令解释器。不多也不少。它和其他任何可执行文件一样是可执行文件,这也意味着它在游戏中只是因为您执行了另一个可执行文件。一些“程序”确实使用“包装器外壳脚本”在执行某些二进制文件或脚本之前设置它们的环境。但这取决于该“程序”的设置方式。但是,通常会为登录的用户创建一个初始 shell 进程,即所谓的“登录 shell”。从该进程衍生出所有其他用户进程。

标签: linux bash shell


【解决方案1】:

shell 只是一种可能的接口。每个 Linux 系统都有一个由内核直接启动的“第一个”进程(通常称为init)的概念。 您计算机上的每个其他程序都由另一个进程启动,该进程首先分叉自己,然后调用 exec(实际上是同一家族中的大约 6 个函数之一)以用不同的程序替换自己。

shell 只是一种可能的接口,一种将文本解析为请求以运行其他程序的接口。 shell 命令行 mv foo bar 被解析为请求传递 fork shell 并在新副本中调用 exec,并使用三个单词 mvfoobar 作为参数。

考虑以下 Python 的 sn-p:

subprocess.call(["mv", "foo", "bar"])

它基本上做同样的事情:Python 程序分叉自己并使用三个给定的字符串作为参数调用exec没有 shell 参与。

【讨论】:

  • 有点离题,但是如果通过 fork 产生另一个进程的进程终止,孩子还能继续吗?换句话说,他们在分叉之后是独立的吗?如果我在前台从 shell 生成进程并关闭 shell,进程也会终止。但是当我在后台(&)运行它时,shell 可能会在没有产生的进程终止的情况下关闭。与分叉有什么关系?另外,超级离题,但是从 docker 容器入口点是从哪里分叉的?
  • @Tuomas:您可能想问一个单独的问题 - 但首先,请阅读有关orphaned processes 的内容。简而言之,ID 为 1 的进程成为孤立进程的父进程。
  • 是的,有些系统具有 Linux 内核但没有外壳 - 例如 Empeg Car 音频播放器,默认情况下将播放器二进制文件作为其初始化进程运行。
【解决方案2】:

shell 只是一个方便的 UI,让您可以按照自己的方式运行其他进程。它也可以运行脚本来做同样的事情。这就是它所做的一切。一旦运行进程,它不负责为进程做任何事情。

你可以用python完全替换它,这样你就可以做同样的事情,但这很烦人,因为你必须输入chepner的subprocess.call(["mv", "foo", "bar"])才能运行mv程序。如果您想将一个程序传送到另一个程序,则需要 5-10 行这样的行。以交互方式编写并没有什么乐趣。

你可以用 KDE/Gnome/whatever 完全替换它,然后双击程序来运行它们,但这不是很灵活,因为你不能包含参数等,而且你不能自动化它。

我知道有两种类型的外壳,交互式外壳和非交互式外壳。终端会话与交互式 shell 交互,脚本在非交互式 shell 中运行。但是除了读取输入和打印输出的能力之外,真的有其他区别吗?

这只是您可以运行sh 的两种不同模式。您需要舒适的键盘快捷键、别名和选项来帮助手动(交互式)输入内容,但在运行预先编写的脚本时它们毫无意义或令人讨厌。

如果我从 shell 调用脚本,它是在这个交互式 shell 中运行还是在 shell 内新的非交互式 shell 中运行?

它在一个新的、独立的进程中运行。您可以在与source yourscript 相同的交互式shell 实例中运行它,这与在键盘上键入脚本内容基本相同。

另外,当我通过交互式 shell 或图形界面调用二进制文件时,它是否总是在 shell 中运行,或者进程可以在没有 shell 的情况下运行?

进程始终完全独立于 shell 运行,但可能共享同一个终端。

据说所有进程都通过shell与内核通信,

进程从不通过 shell 与内核对话。他们通过系统调用进行交谈。

但我很困惑,因为在 docker 中,您可以将入口点定义为二进制文件或“sh -c 二进制文件”。

对于一个简单的二进制文件,两者是相同的。

如果你想,例如设置管道或重定向,因为进程不会自己执行此操作,您可以使用 sh -c 让 shell 执行此操作。

【讨论】:

    猜你喜欢
    • 2018-09-22
    • 1970-01-01
    • 2013-03-14
    • 2011-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-17
    相关资源
    最近更新 更多