Можно ли написать команду оболочки в пределах 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:

  1. 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.
    

Проверьте вашу оболочку, вы должны увидеть результат там.

  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'

Это об этом.

Другие вопросы по тегам