Shell Wrapper PSR

178 views
Skip to first unread message

Xedin Unknown

unread,
Apr 2, 2016, 5:04:31 PM4/2/16
to PHP Framework Interoperability Group
Hi,

I needed an Object Oriented wrapper to run CLI commands in a structured way. However, there wasn't a decent wrapper. The best one I found was php-shell-wrapper, but it was missing what I needed. So, I created it, and filed a pull request. The PR was rejected.

However, I imagine that other people will need shell wrappers too. Maybe Adam Brett will want to implement the wrapper to a different way to what I did. But there's no standard, and so we are stuck not only being coupled to a specific implementation, but we can't even change the implementation easily if we become unsatisfied with it.

So, I thought that maybe a standard would be good, and I created shell-interop. At present there is only a specification in the wiki, but I will work on the interfaces soon. Any chance this can become a PSR? Even if not, feedback would be greatly appreciated!

Matthew Kaufman

unread,
Apr 2, 2016, 6:14:04 PM4/2/16
to php...@googlegroups.com
Wonderful!

--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/php-fig/6e3c6f33-3628-46ac-8a0d-0d3852a6e94f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Xedin Unknown

unread,
Apr 3, 2016, 11:20:25 AM4/3/16
to PHP Framework Interoperability Group
There's now also shell-command-interop.

Xedin Unknown

unread,
Apr 3, 2016, 11:22:29 AM4/3/16
to PHP Framework Interoperability Group
Also, forgot to mention that I added 3 required and 1 optional interfaces.


On Saturday, April 2, 2016 at 11:04:31 PM UTC+2, Xedin Unknown wrote:

Xedin Unknown

unread,
Apr 3, 2016, 12:00:38 PM4/3/16
to PHP Framework Interoperability Group
shell-command-interop now includes all interfaces described in the specification.


On Saturday, April 2, 2016 at 11:04:31 PM UTC+2, Xedin Unknown wrote:

Tim Otten

unread,
Apr 5, 2016, 12:01:35 AM4/5/16
to PHP Framework Interoperability Group
1. Could you give more concrete examples of when libraries would implement the interfaces? Maybe use some example shell commands (e.g. iptables, lvm, git, composer) and some example strategies for providing a shell (e.g. proc_open, ssh+passwd, ssh+key, sudo, su)?

2. In symfony/process, I like that they provide ways to access the command output synchronously or asynchronously. If I read correctly, CommandResultInterface implies synchronous execution (stdout/stderr as blobs). For someone trying to parse the output of a long-running command (or dealing with any command which has prompts), an async/streaming interface seems pretty useful.

Xedin Unknown

unread,
Apr 5, 2016, 1:20:37 AM4/5/16
to PHP Framework Interoperability Group
Hi Tim,

And thank you for your feedback. Below I will try to address your points:

As I explained in the first post, I originally needed a library that would give me a convenient way to do 2 things:
    1. A convenient way to invoke shell commands.
      I think that proc_open(), which is the only function that allows the user to get both the standard and error output, and the exit code, is way too complicated to be used comfortably. Also, the developer would have to first learn of all the disadvantages of other functions, such as exec() and passthrough(), and that they don't do what the developer needs. In fact, it beats me why exec() can provide output from stdout, but not stderr.
    2. A convenient way to build shell commands.
      Shell commands have structure, where the "parameters" of the command follow the main command, and in a specific order. Also, many times values have to be escaped. There are tools for building MySQL queries in PHP. So, I figured it would be very convenient if there was a way to build shell commands in a similar way. This could make a large part of a command re-usable, would make the command safer and easier to work with.
I wanted the things that build and run my commands to be de-coupled from the rest of the application, e.g. be in a separate library. However, I also wanted the users of my library to be free from my library. So, I thought it would be a good idea to create a standard first that, if followed, would allow the users of my library to choose an implementation that they prefer, without having to re-write their application. Hence, I came up with 2 standards greatly inspired by container-interop and definition-interop, which are 2 separate standards that work together to provide ways of being independent from any specific library that runs shell commands or builds shell commands, such as my library shell or the above mentioned php-shell-wrapper.

As for examples, one could certainly use it with specifically git or composer, perhaps to build a convenient API for them - which is exactly why I need all this in fact! However, this would bring most benefit if used by generic shell wrappers like the ones I mention above, that can run any commands. In fact, I already have a non standards-compliant implementation that I suggested here. Now I realize that it's best if I create a lib of my own, that is standards-compliant. This implementation is based around proc_open().
I haven't yet tried, but I believe that with it, acquiring and SSH shell would be possible. I believe that later on, a more convenient wrapper can be implemented around that. However, if I'm missing something, please do tell me, your feedback is very much appreciated.


With regard to your second point, if you take a look at my old implementation, it solves the problem of async output by using callbacks. I think this is very flexible, as when a callback is executed, the user is free in what to do: write to a stream, or to a concrete file.
Do you think there's a better way to do that?
Reply all
Reply to author
Forward
0 new messages