Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to write shell command within Pharo smalltalk?

Like in other programming language, is there a way of running linux shell command in Pharo smalltalk or a simple script ? I would like to have my Pharo image running a script that should be able to automate a tasks and return it to some value. I looked at almost all the documentation around and I couldn't find anything related. Maybe It does not allow such functionality.

like image 571
ludo Avatar asked Jul 16 '18 13:07

ludo


People also ask

What is shell script command?

A shell script is a text file that contains a sequence of commands for a UNIX-based operating system. It is called a shell script because it combines a sequence of commands, that would otherwise have to be typed into the keyboard one at a time, into a single script.

How do you store variables in shell?

To store the output of a command in a variable, you can use the shell command substitution feature in the forms below: variable_name=$(command) variable_name=$(command [option ...] arg1 arg2 ...) OR variable_name='command' variable_name='command [option ...]


1 Answers

Pharo does allow the OS interaction. The best way, in my eyes, is to use OSProcess (as MartinW already suggested).

Those that think it is a duplicate are missing this part:

... running a script that should be able to automate a tasks and return it to some value...

There is nothing about return value in the invoking shell commands from squeak or pharo

To get a return value you would do it the following way:

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

If you print out the above code you will get most probably a 0 as success.

If you do an obvious error:

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

You will get ~= 0 value in my case 512.

Edit adding more details to cover more ground

I agree with eMBee that a statement

return it to some value

is rather vague. I'm adding information about I/Os.

As you may know there are three basic IO: stdin, stdout, and stderr. These you need to interact with shell. I'll add these examples first then I'll get back to your description.

Each of them is represented by instance of AttachableFileStream in Pharo. For the above command you will get initialStdIn (stdin), initialStdOut (stdout), initialStdError (stderr).

To write into the terminal from Pharo:

  1. stdout and stderr (you stream string into terminal)

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

Check your shell you should see the output there.

  1. stdin - to get what you typed

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

If you want to grab an output from the command into Pharo a resonable way is to use PipeableOSProcess which, as apparent from his name, can be used in conjunction with pipes.

Simple example:

| commandOutput |

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

More complex example:

| commandOutput |

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

I like the use of outputAndError because of typos. If you have an incorrect command you will get the error message:

| commandOutput |

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

In this case '/bin/sh: cot: command not found'

That is about it.

Update 29-3-2021 The OSProcess works up to Pharo 7. It was not upgraded to work with the changes at Pharo 8 or newer.

like image 105
tukan Avatar answered Nov 02 '22 23:11

tukan