In Fabric 2/Invoke: change directory and use sudo
Asked Answered
D

2

9

This works just fine

@task
def foo(context):
    with context.cd('/'):
        context.run('pwd')

Output:

/

But this does not:

@task
def bar(context):
    with context.cd('/'):
        context.sudo('pwd', password='mysecretpassword')

Output:

[sudo] password: sudo: cd: Befehl nicht gefunden

How do I get the second example to run?

Dikmen answered 13/6, 2018 at 9:48 Comment(0)
D
4

It turns out, that this is a bug in invoke yet to be fixed.

https://github.com/pyinvoke/invoke/issues/459

Edit:

This is my workaround for now:

context.sudo('bash -c cd "/ && pwd"')

Dikmen answered 13/6, 2018 at 17:50 Comment(0)
D
2

Extending @mogoh answer a bit.

The correct way is to include the whole command in double quotes, like this:

context.sudo('bash -c "cd /some/path && ls"')

As the commands can grow quite big and to follow DRY principles, I created a function to do wrap this:

def sudo_cd(context, path, command):
    """Workaround on the problem of cd not working with sudo command"""
    context.sudo(f'bash -c "cd {path} && {command}"')

For the example above, we use it like this:

sudo_cd(context, '/some/path', 'ls')

Danialah answered 21/4, 2020 at 17:46 Comment(1)
For those who don't know what the f means before the string. Is a new way to format text strings introduced in python 3.6. It's beautiful and simpler than all other methods: python.org/dev/peps/pep-0498Danialah

© 2022 - 2024 — McMap. All rights reserved.