from pyshell import sh, ShellError
def func(a,b)
output, retcode = sh("df -k | awk '{print $5}'")
if retcode == 0:
return output
else:
raise ShellError(output,retcode)I was also planning to extend it to support python3 asyncio, but never got around it
It provides an idiomatic shell scripting experience for python.
For example, it uses the "pipe" operator overload to allow complex pipelines to be created (pipes are created using platform native pipes, so there's no performance difference from a shell pipeline). The same operator can also be used for redirections
By the way, why not put the raise inside sh?
EDIT: Ok, the difference is that os.system does not return stdout. But you can use the subprocess package to capture stdout (and stderr as well). If you want pipe syntax, you can invoke e.g. bash -c "...", where the dots are your command. But the problem with this is that it's prone to injection attacks, unless you are very careful. I guess the same warning applies in your original "sh" example.
>>> from invoke import run
>>> date = run("date")
Sat Apr 13 11:09:18 PDT 2019
>>> dir(date)
['__bool__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__nonzero__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'command', 'encoding', 'env', 'exited', 'failed', 'hide', 'ok', 'pty', 'return_code', 'shell', 'stderr', 'stdout']
>>> date.return_code
0
>>> date.stdout
'Sat Apr 13 11:09:18 PDT 2019\n'
>>> do_they_exist = run("grep banana /etc/passwd")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/pgraydon/Envs/python3/lib/python3.7/site-packages/invoke/__init__.py", line 46, in run
return Context().run(command, **kwargs)
File "/Users/pgraydon/Envs/python3/lib/python3.7/site-packages/invoke/context.py", line 94, in run
return self._run(runner, command, **kwargs)
File "/Users/pgraydon/Envs/python3/lib/python3.7/site-packages/invoke/context.py", line 101, in _run
return runner.run(command, **kwargs)
File "/Users/pgraydon/Envs/python3/lib/python3.7/site-packages/invoke/runners.py", line 271, in run
return self._run_body(command, **kwargs)
File "/Users/pgraydon/Envs/python3/lib/python3.7/site-packages/invoke/runners.py", line 404, in _run_body
raise UnexpectedExit(result)
invoke.exceptions.UnexpectedExit: Encountered a bad command exit code!
Command: 'grep banana /etc/passwd'
Exit code: 1
Stdout: already printed
Stderr: already printed
If it gets a non-zero code back (like grep does when it fails to get a match), it raises an UnexpectedExit exception.http://ibmsystemsmag.com/aix/tipstechniques/systemsmanagemen...
https://redpanthers.co/different-ways-to-run-shell-commands-...
Perl/awk like one-liner/filters in ruby:
http://reference.jumpingmonkey.org/programming_languages/rub...
https://nithinbekal.com/posts/ruby-sed-awk/
Of note is that ruby allows "backtick execution":
filename = 'some_file.txt' wordcount = `wc --words #{filename}`
I find that much of the strength of bash/shell comes from the surrounding utilities though. So simply jumping to ruby won't magically let your "shell script" work on both windows and Linux, just because you have ruby installed;there likely not be a similar set of building blocks like "wc" etc. You could of course replicate most via the ruby std lib - and it's arguably easier to write test driven ruby than bash.
qx(some command some parameters some variables)seems a lot of effort and iterations went into this?
I have seen quite a bit of legacy plumbing like this in production / automation until better (or at least standardized) tooling came along with the agile/devops movement. A lot of this plumbing survived surprisingly long (which is also scary). Often code like this matures over long periods into stable solutions that could even deal with errors well. Makes them hard to replace.
I agree it doesn't belong in production but it looks pretty neat for small internal stuff even in 2019.
Learning from books doesn't work, you need to have a project with a goal to apply it in.
The horrible honest truth is that the world actually doesn't run on bash, python, C or Java.
It runs on Excel macro's.
Your project is a great read!
It's a huge bash script for parallel processing of work. It was great fun and I'm proud of it as I don't see myself as a programmer of any sort.
But gosh since I learned Powershell and Python, I would never ever ever ever ever use Bash for anything substantial.
If you ever feel like you grow 'fond' of Bash or Shell scripting, it's time to seek a doctor. Please learn Python or some equivalent instead.
-----------------
Edit: reading the code of this web server project:
Let's be absolutely clear: this is a joke project. DO NOT USE THIS FOR # ANYTHING, ESPECIALLY ON A PUBLIC FACING SERVER.