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.
在我的情况下,您将获得 ~= 0 值 512。
编辑添加更多细节以涵盖更多领域
我同意 eMBee 的说法
返回某个值
比较模糊。我正在添加有关 I/O 的信息。
您可能知道有三个基本 IO:stdin、stdout 和 stderr。这些你需要与 shell 交互。我会先添加这些示例,然后再回到您的描述中。
它们中的每一个都由 Pharo 中的 AttachableFileStream 实例表示。对于上述command,您将获得initialStdIn (stdin)、initialStdOut (stdout)、initialStdError (stderr)。
将写入终端来自 Pharo:
-
stdout 和 stderr(将字符串流式传输到终端)
| 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,你应该会在那里看到输出。
-
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 或更高版本的更改。