【发布时间】:2016-07-11 07:35:49
【问题描述】:
我需要从程序中确定 Linux 命令是否是内置命令。我还需要偶尔运行该内置命令。我将以别名为例,它也适用于其他内置函数。
我找到的一个恰当的答案是使用:
sh -c 'type alias'
这将返回“别名是内置的 shell”,这正是我所需要的。但是...我也需要运行它。我尝试过的任何事情都不会这样做。所有这些都在终端窗口中失败(并以编程方式):
-
sh -c 'alias'(没有任何输出) -
sh -c 'command alias'(没有任何输出) -
sh -c 'builtin alias'(sh: 1: builtin: not found) -
sh -c 'type builtin'(内置:未找到) -
sh -c 'type command'(命令是内置的shell) -
sh -c 'type type'(类型是内置的 shell)
(几乎)不用说,所有这些命令(即,没有sh -c)在终端上都可以正常工作。这让我对 sh -c 命令看似不合理的性质感到困惑。
我的问题是:所有 Linux 版本都是这样吗?我是否缺少开关或设置?那么,我怎样才能从一个程序中执行一个内置函数以取回它的输出呢?
我正在开发 Kubuntu 14.04(在 Trisquel 中也是如此);在konsole 和xterm 以及程序调用中都会出现此问题。
感谢您的cmets和答案,非常感谢。
我确实需要澄清我在做什么:我正在编写一个 CLI 辅助 GUI,一个用于存储和执行最喜欢的 linux 命令的程序。
我使用 freepascal / Lazarus,它有一个 TProcess 类,它启动一个进程并提供对标准输入、标准输出和标准错误的访问权限。
这非常适用于基于文件的命令(例如 rsync 等),并且我在输入和输出文本时没有问题。我什至可以复制管道,只需将输出从一个进程传递到另一个进程的输入。但是……
...内置的不是这样。这让我走上了研究别名等的道路。
我希望我的程序也包含内置的,但第一个问题是如何在添加时判断它是否是内置的(是的,内置的列表是有限的,但以后可以扩展它,我想要我的程序来处理这种可能性)。因此我研究并发现了 sh -c 'type cmd'。
现在我可以确定命令是基于文件(使用哪个)还是内置(使用上面的表达式)。
虽然通过我的程序运行内置程序不会有很大的需求,但偶尔从一个程序中获取输出很有用。例如,别名。不带参数运行时的别名等效于 alias -p ,它只是输出系统中注册的当前别名。
但这就是障碍所在。如上所示,我似乎无法获得输出。
我现在明白了 subshell 的概念,这就解释了为什么我什么也没得到(我怀疑它与输出有关)。
很遗憾,到目前为止所有建议都不起作用。例如, eval 命令(谢谢你,我不知道那个)。它是内置的。所以我知道(尝试)获得输出的唯一方法是使用 sh -c 'eval alias',它什么都不返回,因为它是子壳。
那么有没有办法让子shell的输出回到我开始的进程?请记住,我是通过我创建的进程以编程方式执行此操作的(但这个问题也反映在终端中,同样的事情也会发生)。
我还想评论一些其他的cmets:
是的,我一直在考虑写一个 bash sh 文件并运行它,但我不会遇到同样的问题吗?
简单地运行命令(通过我创建的进程)会导致异常,因为该进程对shell一无所知,所以只运行文件,没有找到内置的,所以失败,这就是为什么 sh -c,或类似的东西,是我唯一的选择。
为什么我需要运行别名?好吧,这只是一个例子,就像我说这是一个内置问题,我使用别名作为例子。但是,就我个人而言,我喜欢 alias,也许我的一些用户也喜欢。
最后一个观察:为什么sh -c 'type alias' 有效?如果sh -c 'command alias' 的原因是因为它被分壳而不返回任何输出,那么为什么type 版本有效?类型特殊?这就是我看到不合理之处的地方。
【问题讨论】:
-
sh -c打开一个没有定义别名的子shell。这就是为什么它什么都不返回。试试bash -c 'alias "a=blah";alias' -
您可以在 bash 脚本中使用
type命令,然后根据返回字符串以编程方式决定要执行的操作。 -
内置插件列表变化不大。为什么你认为你需要做实验?为什么它们是否是内置的很重要?只需运行命令——它们应该可以工作。
-
为什么需要运行
alias?任何人都不应该使用别名。 -
“CLI 助手 GUI”不应该使用 shell -- 没有
sh -c或bash -c或其他任何东西 -- 除非你真的知道你是什么正在做。 Shell 注入攻击与 SQL 注入攻击一样严重。如果您的用户在他们的配置中指定了一个文字 argv 数组,那么当且仅当他们真的想要并且有理由需要一个 shell 时,他们才可以指定一个 shell。
标签: bash shell command-line-interface