plumbum icon indicating copy to clipboard operation
plumbum copied to clipboard

Log command being executed

Open yajo opened this issue 5 years ago • 4 comments

In my bash scripts I can use set -x at the beginning, so bash keeps printing the command being executed.

I found nothing similar in plumbum. I even tried with:

logging.getLogger("plumbum.local").setLevel(logging.DEBUG)

... no luck.

There should be a standard and documented way to make plumbum print the command it's going to execute. I guess a logger should do the trick. Example:

logging.getLogger("plumbum.command").setLevel(logging.INFO)  # This prints just the command to be executed
logging.getLogger("plumbum.command").setLevel(logging.DEBUG)  # This prints additional details, and also prints when the command has finished

Thanks!

yajo avatar Oct 16 '19 09:10 yajo

Have you seen the LocalCommand's formulate method? You might do something like this:

In [1]: from plumbum.cmd import uptime

In [2]: up = uptime['--pretty']

In [3]: up()
Out[3]: 'up 1 day, 23 minutes\n'

In [4]: up.run_fg()
up 1 day, 23 minutes

In [5]: import sys

In [6]: def logrun(cmd, fg=False):
   ...:     print(cmd.formulate(), file=sys.stderr)
   ...:     if not fg:
   ...:         return cmd()
   ...:     cmd.run_fg()
   ...:

In [7]: logrun(up)
['/bin/uptime', '--pretty']
Out[7]: 'up 1 day, 25 minutes\n'

In [8]: logrun(up, fg=True)           
['/bin/uptime', '--pretty']
up 1 day, 28 minutes

AndydeCleyre avatar Nov 16 '19 21:11 AndydeCleyre

Oh yes, it seems pretty close to what I want.

However I'm thinking on a replacement of Bash's set -x, which always outputs commands before their execution.

For things like CI environments, where you usually want to know at which step a given command has failed, it's very useful. I miss an equivalent in plumbum, which I think could be supported upstream with a logger that always logs the command if instructed. It could be also attached to the machine log level. Something like:

import logging
from plumbum import local, SshMachine

local.log_level = logging.DEBUG
remote = SshMachine("example.com")
remote.log_level = logging.INFO

yajo avatar Nov 17 '19 12:11 yajo

This is a very important feature. And it's missing. Must be made available as part of the package. Something similar to below could help build the feature into the package: https://gist.github.com/bgreenlee/1402841

imperialguy avatar Nov 11 '20 21:11 imperialguy

I'm not sure if this is what you are looking for, but I've used shlex to generate "copy & pastable" commands. Shlex takes an array (such as the output of formulate) and creates a command with proper quoting, essentially the same as set -x.

import shlex

cmd = local['ls']['-l', 'some file with spaces']
print(shlex.join(cmd.formulate()))

that outputs: /usr/bin/ls -l 'some file with spaces'

8cylinder avatar Jun 20 '21 22:06 8cylinder