invoke: sudo() doesn't play nice with shell syntax (&&, ;, etc) such as what cd() does

As cd is a shell builtin, it can’t be executed as a sudo command. When I do that:

@task
def test(ctx):
    """ test command """
    with ctx.cd('my/path'):
        ctx.run("pwd") # Show correct path
        ctx.sudo("whoami") # fails with: sudo: cd: command not found

The last command fail.

After a quick look in the source, sudo command appears to be:

cmd_str = "sudo -S -p '{0}' {1}{2}".format(prompt, user_flags, command)

with the cd prefix the executed command is

$ sudo -S -p cd my/path && whoami

where cd is unknow inside sudo.

To fix the issue, new sudo command could be:

cmd_str = "sudo -S -p '{0}' {1} sh -c \"{2}\"".format(prompt, user_flags, command)

but not sure of all the consequences of this behaviour.

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Reactions: 15
  • Comments: 15 (4 by maintainers)

Commits related to this issue

Most upvoted comments

Have exactly the same problem since fabric1, today have ported my code from fabric 1 to fabric 2 and found out that is still not fixed

Belatedly sticking this in my priority queue as I get back into things here. I’m honestly not sure why I had it marked as bugfix since most solutions outlined are “feature sized”. Not like it matters when these tickets stick around for so long 😩

Are there any chances for workaround to get merged ? 😄