sh commands¶
XAL provides an interface to run shell commands through sh
.
Tip
With a local session, XAL is a convenient subprocess wrapper.
Differences with subprocess¶
XAL’s sh
interface is made to run sh
commands in a session.
Think of the commands always run with sh -c
.
Whereas Python’s subprocess sets shell=False
by default.
This postulate influences design. XAL’s sh interface helps you create and run
commands through sh
: pipes, redirects...
“sh” provider in session’s registry¶
Let’s start with a local session:
>>> from xal.session.local import LocalSession
>>> session = LocalSession()
By default, in LocalSession
, “sh” provider is
xal.sh.local.LocalShProvider
:
>>> session.registry.default('sh') # Doctest: +ELLIPSIS
<xal.sh.local.LocalShProvider object at 0x...>
For convenience, we will set sh
as a shortcut for session.sh
:
>>> sh = session.sh
The ShCommand resource¶
The sh
interface can be used as a factory to create
xal.sh.resource.ShCommand
resources:
>>> sh("echo -n 'Hello world!'") # Doctest: +ELLIPSIS
<xal.sh.resource.ShCommand object at 0x...>
Command resources are not executed automatically once created.
You have to run them explicitely. They are callables.
When called, they return a xal.sh.resource.ShResult
instance:
>>> command = sh("echo -n 'Hello world!'")
>>> result = command()
>>> result # Doctest: +ELLIPSIS
<xal.sh.resource.ShResult object at 0x...>
>>> result.stdout
'Hello world!'
>>> result.return_code
0
>>> result.succeeded
True
Command constructor accepts strings or iterables:
>>> sh("echo -n 'Hello world!'")().stdout
'Hello world!'
>>> sh(["echo", "-n", "Hello world!"])().stdout
'Hello world!'
The sh
interface has a run()
shortcut that creates and runs Cmd
instances:
>>> sh.run("echo -n 'Hello world!'").stdout
'Hello world!'
>>> sh.run(["echo", "-n", "Hello world!"]).stdout
'Hello world!'
>>> command = sh("echo -n 'Hello world!'")
>>> sh.run(command).stdout
'Hello world!'
You can create a resource for later use in one or several sessions:
>>> hello = sh("echo -n 'Hello world!'")
>>> from xal.session.local import LocalSession
>>> session = LocalSession()
>>> session.sh.run(hello).stdout
'Hello world!'
Pipes¶
You can create and handle pipes, they are commands too:
>>> echo = sh("echo -e 'hello\nworld'")
>>> grep = sh("grep 'world'")
>>> piped = echo.pipe(grep)
>>> piped().stdout
'world\n'
>>> piped = echo | grep
>>> piped().stdout
'world\n'
>>> sh.run(echo | grep).stdout
'world\n'