-->

Invoking shell commands from Squeak or Pharo

2020-02-26 09:29发布

问题:

How can you invoke shell commands from Squeak and Pharo? Do these environments have anything in them like the system() function in certain unix languages to run external shell commands, or the backticks (can't make them here do to the editor, but what you get when you push the key left of "1" and above "TAB") to capture the output of commands?

回答1:

In Squeak you can use CommandShell, but I don't know what (if anything) is available for Pharo at this time.



回答2:

I think you can use the package OSProcess to do what you want. In addition, I think is better to ask in squeak-dev or pharo mailing list.



回答3:

Shell support in Squeak/Pharo is pretty limited. There are plans to get this improved; see the Coral project. Your contributions are welcome.



回答4:

You have two solutions:

Use the package ProcessWrapper. Pros: quick and easy install. Cons: limited functionality, only on win32.

Use the package OSProcess/CommandShell. Pros: pretty good functionality (pipes, environment vars, shell-like workspace ...), and cross platform. Cons: must use VMMaker tools to build the external plugin.



回答5:

I'm using Windows 10 with Pharo 6, and found it unfeasible to use the OSProcess or OSSubprocess classes (hard to install or the latest versions are not supported for Windows).

What does work for me is LibC. You can redirect stderr to a file using 2> inside the command:

errors := '/tmp/errors.txt'.
result := LibC uniqueInstance system: 
    'echo "Hello World" > /tmp/hello.txt 2>', errors.
result = 0 ifFalse: [ errors asFileReference ]

It's possible to manipulate the environment variables using (although it returns a value of 1 implying failure in Windows):

   OSEnvironment current setEnv: 'MY_ENVIRONMENT_VARIABLE' value: '1'.

However, I was unable to change the current directory:

OSEnvironment current changeDirectoryTo: myDirectory asFileReference. "--> doesNotUnderstand for Windows"

The workaround is to do CD within the command:

result := LibC uniqueInstance system: 
    'cd ', myDirectory, ' && ls > /tmp/output.txt 2>', errors.


回答6:

On Windows, there is a wrapper on the Win API allowing you to do this:

| sqlPlusExe sqlPlusRunInDir scriptPathString| 

scriptPathString := (FileLocator imageDirectory / 'data' / 'sqlplus' / 'testquit.sql') pathString.

sqlPlusExe :='C:\oraclexe\app\oracle\product\11.2.0\server\bin\sqlplus.exe /nolog @' , scriptPathString.
sqlPlusRunInDir := 'C:\oraclexe\app\oracle\product\11.2.0\server\bin'.

sqlPlusWinProcessInformation := WinProcess 
        createAndWaitForProcess: sqlPlusExe 
        withCurrentDirectory: sqlPlusRunInDir 

There are a lot of support for most of what Windows can do with processes in there (env, ...)

So, look in the catalog for OSWindows.