Можно ли написать команду оболочки в пределах Pharo smalltalk?
Как и в других языках программирования, есть ли способ запустить команду оболочки Linux в Pharo smalltalk или в простом скрипте? Я хотел бы, чтобы на моем образе Pharo был запущен скрипт, который должен быть в состоянии автоматизировать задачи и вернуть ему какое-то значение. Я просмотрел почти всю документацию вокруг и не смог найти ничего связанного. Может быть, это не позволяет такой функциональности.
1 ответ
Pharo разрешает взаимодействие с ОС. На мой взгляд, лучший способ - это использовать OSProcess
(как уже предложил MartinW).
Те, кто думают, что это дубликат, пропускают эту часть:
... запуск сценария, который должен быть в состоянии автоматизировать задачи и вернуть ему какое-то значение...
В вызывающих командах оболочки от squeak или pharo нет ничего о возвращаемом значении
Чтобы получить возвращаемое значение, вы должны сделать это следующим образом:
command := OSProcess waitForCommand: 'ls -la'.
command exitStatus.
Если вы распечатаете вышеприведенный код, вы, скорее всего, получите 0
как успех
Если вы делаете очевидную ошибку:
command := OSProcess waitForCommand: 'ls -la /dir-does-not-exists'.
command exitStatus.
Ты получишь ~= 0
ценность в моем случае 512
,
Изменить, добавив больше деталей, чтобы покрыть больше земли
Я согласен с eMBee, что заявление
вернуть это значение
довольно расплывчато Я добавляю информацию о входах / выходах.
Как вы, возможно, знаете, есть три основных ввода-вывода: stdin
, stdout
, а также stderr
, Эти вам нужно взаимодействовать с оболочкой. Сначала я добавлю эти примеры, а затем вернусь к вашему описанию.
Каждый из них представлен экземпляром 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.
Проверьте вашу оболочку, вы должны увидеть результат там.
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'
Это об этом.