【问题标题】:Is it possible to write shell command within Pharo smalltalk?是否可以在 Pharo smalltalk 中编写 shell 命令?
【发布时间】:2018-07-16 13:35:38
【问题描述】:

和其他编程语言一样,有没有办法在 Pharo smalltalk 或简单的脚本中运行 linux shell 命令?我想让我的 Pharo 图像运行一个脚本,该脚本应该能够自动执行任务并将其返回到某个值。我查看了几乎所有的文档,但找不到任何相关内容。也许它不允许这样的功能。

【问题讨论】:

  • @eMBee 怎么是重复的?
  • 您想在 Pharo 中调用命令行工具还是使用 Pharo 编写命令行工具?第一个是Invoking shell commands from Squeak or Pharo 的副本。从 Pharo 项目目录安装 OSProcess 将是一个解决方案。
  • 您要求运行一个 shell 命令并获得一些返回值。另一个问题是关于调用 shell 命令和捕获输出。这些几乎是一回事。你的问题的答案也可以是另一个问题的答案。另一个问题的唯一问题是没有答案解释如何捕获输出。我建议您的问题可能是重复的。我并不是说它是。如果您的问题有任何不同,请随时详细说明。
  • 照原样,我建议将两个问题的答案合并,并将一个问题标记为与另一个问题重复。

标签: linux shell smalltalk pharo pharo-5


【解决方案1】:

Pharo 确实允许操作系统交互。在我看来,最好的方法是使用OSProcess(正如MartinW 已经建议的那样)。

那些认为它是重复的人错过了这部分:

...运行一个应该能够自动执行任务的脚本,并且 将其返回到某个值...

invoking shell commands from squeak or pharo中没有关于返回值的内容

要获得返回值,您可以通过以下方式进行:

command := OSProcess waitForCommand: 'ls -la'.
command exitStatus.

如果你打印出上面的代码,你很可能会得到一个0 作为成功。

如果你犯了明显的错误:

command := OSProcess waitForCommand: 'ls -la /dir-does-not-exists'.
command exitStatus.

在我的情况下,您将获得 ~= 0512

编辑添加更多细节以涵盖更多领域

我同意 eMBee 的说法

返回某个值

比较模糊。我正在添加有关 I/O 的信息。

您可能知道有三个基本 IO:stdinstdoutstderr。这些你需要与 shell 交互。我会先添加这些示例,然后再回到您的描述中。

它们中的每一个都由 Pharo 中的 AttachableFileStream 实例表示。对于上述command,您将获得initialStdIn (stdin)、initialStdOut (stdout)、initialStdError (stderr)。

写入终端来自 Pharo:

  1. stdoutstderr(将字符串流式传输到终端)

    | process |
    
    process := OSProcess thisOSProcess.
    process stdOut nextPutAll: 'stdout: All your base belong to us'; nextPut: Character lf.
    process stdErr nextPutAll: 'stderr: All your base belong to us'; nextPut: Character lf.
    

检查你的 shell,你应该会在那里看到输出。

  1. stdin - 获取您输入的内容

    | userInput handle fetchUserInput |
    
    userInput := OSProcess thisOSProcess stdIn.
    handle := userInput ioHandle.
    "You need this in order to use terminal -> add stdion"
    OSProcess accessor setNonBlocking: handle.
    fetchUserInput := OS2Process thisOSProcess stdIn next.
    "Set blocking back to the handle"
    OSProcess accessor setBlocking: handle.
    "Gets you one input character"
    fetchUserInput inspect.
    

如果你想命令进入 Pharo获取输出,一个合理的方法是使用PipeableOSProcess,从他的名字可以看出,它可以用于与管道结合使用。

简单示例:

| commandOutput |

commandOutput := (PipeableOSProcess command: 'ls -la') output.
commandOutput inspect.

更复杂的例子:

| commandOutput |

commandOutput := ((PipeableOSProcess command: 'ps -ef') | 'grep pharo') outputAndError.
commandOutput inspect.

由于拼写错误,我喜欢使用outputAndError。如果您的命令不正确,您将收到错误消息:

| commandOutput |

commandOutput := ((PipeableOSProcess command: 'ps -ef') | 'grep pharo' | 'cot') outputAndError.
commandOutput  inspect.

在这种情况下'/bin/sh: cot: command not found'

就是这样。

2021 年 3 月 29 日更新OSProcess 适用于 Pharo 7。它未升级为适用于 Pharo 8 或更高版本的更改。

【讨论】:

  • “从 squeak 或 pharo 调用 shell 命令中没有任何关于返回值的内容”:嗯,另一个问题确实提到了“捕获命令的输出”,所以是的,这个问题确实要求返回值。不过你的回答比其他人好。
  • 顺便说一句:这两个问题都不清楚他们到底想要哪个值。无论是 exitstatus 还是 stdout 或 stderr 上的输出。如果您可以将两者都添加到您的答案中,那就太好了。
  • @eMBee 你是对的。我已经添加了两种方式。
  • @eMBee 呵呵,很高兴你喜欢。
猜你喜欢
  • 2016-02-19
  • 1970-01-01
  • 1970-01-01
  • 2014-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-15
相关资源
最近更新 更多