Reputation: 741
I am new to Fabric and I am trying to cd into a directory I don't have permission to, so I'm using sudo
. (The permissions on the directory are drwx------, i.e., 700)
I am using Fabric 0.9.7.
I tried this:
from fabric.api import run, env
from fabric.context_managers import cd
env.hosts = [ '1.2.3.4' ]
env.user = 'username'
def test():
run('sudo cd /my/dir')
run('ls')
But this gives me "sorry, you must have a tty to run sudo" which is understandable. I've also tried this:
snip:
def test():
with cd('/my/dir'):
run('ls')
But this returns "permission denied", again understandable.
In a nutshell, how do I "sudo cd
" within Fabric?
Upvotes: 3
Views: 4320
Reputation: 18973
As others have explained, cd
is a shell builtin in Linux, but sudo
only works with executables, so sudo cd
cannot work.
Therefore even using with c.cd()
and sudo()
with latest Fabric does not work, this task:
@task
def pwd(c):
with c.cd('/tmp'):
c.sudo('pwd')
results in the following error:
sudo: cd: command not found
The arguably unattractive workaround is to launch a new shell with sudo()
for the command and manually prefix it with cd
:
@task
def pwd(c):
c.sudo('sh -c "cd /tmp && pwd"')
See this Invoke issue.
Upvotes: 4
Reputation: 54272
Is there any reason you're not just using sudo()
? It may work around the issue you're having.
If you're using a version of Fabric before 1.0, you'll need to explicitly tell it to create a TTY:
sudo("ls", pty=True)
Otherwise, you may need to edit your sudoers file and remove or comment out this line:
Defaults requiretty
Should be:
#Defaults requiretty
Also, it may be more annoying, but if with cd(...)
causes problems, you can always pass the path as an argument to ls
:
sudo("ls /my/dir")
Upvotes: 3
Reputation: 23346
This is because cd
is a shell builtin command and not an actual program that can be run with sudo
. You were on the right track with with cd(...):
. Try something like:
with cd('/my/dir'):
sudo('ls')
I think that will work, though admittedly I have not yet tried it myself. That's because the way the cd
context manager works is to prepend cd <dirname> &&
to any command run with run()
or sudo()
.
Upvotes: 1