Providing input to command (su) executed using Python Paramiko Transport class due to special authentication needs
The low-level Channel.exec_command
does not return anything (unlike the high-level SSHClient.exec_command
).
If you want to obtain the I/O, you have to call Channel
's makefile*
methods.
This is simplified code of what SSHClient.exec_command
does internally:
chan = transport.open_session()
chan.exec_command(command)
stdin = chan.makefile_stdin("wb", bufsize)
stdout = chan.makefile("r", bufsize)
stderr = chan.makefile_stderr("r", bufsize)
Running a python script on a remote server with sudo privileges
The problems in the above script were:
i = child.expect(['[sudo] password for zod1:'])
Here,
[sudo]
was not escaped like\[sudo\]
hence, pexpect was not able to
find match since it expects a pattern.child = pexpect.spawn('sudo su')
spawned a new independent process
instead of continuing with the already spawned process. Usingchild.sendline('sudo su')
resolved the issue.
How to execute 'su' command using parallel-ssh
It turns out that what I am trying to do is not achievable.
The first problem
I found in this post that all commands are in their own channel. That means that even if su
would be successful it wouldn't affect the second command. The author of the post recommends running
su -c whoami - root
The second problem
I managed to debug the problem even further by changing host_output.stdout
to host_output.stderr
It turned out that I receive an error which previously was not being shown on the terminal:
standard in must be a tty
Possible solutions to this problem are here . They didn't work for me but might work for you.
For me workaround was to allow on all my hosts root login. And then in parallel-ssh I log in as a root already with all the rights in place.
using subprocess to ssh and execute commands
I figured the solution by using univerio's comment
The command needs to be
command = 'ssh -t -t buildMachine.X.lan \'sudo su - buildbot \'build-set sets/set123\'\''
Individual commands are like argument to previous command. This works.
Execute a Command on a Remote Server That Requires Sudo with password input - Paramiko
A few years ago I have had similar issues, and it turns out that there might be a few reasons for that.
One possible option is that the call waits to get a shell prompt in order to return. However, in the case of a command that requires sudo
, the behavior might change: In some cases, it will require you to enter the password first. In other cases (e.g., if you have just used sudo
and it was not timed out yet), it will not require the password again. This inconsistency might cause problems.
Take a look here - using -k
might solve your problem.
In order to solve that, you have to define (if possible) that sudo
will always require a password, thus make it consistent.
Another issue that might raise is the definition of the shell prompt (some shells use >
, others use $
); the same might be true for the sudo
- it might print Password:
, which contains no shell prompt and might not be recognized by the remote-command agent, and it might print something else, e.g. password
.
Executing su user (without password) on paramiko ssh connection
Each exec_command()
call happens in a new shell, so there is no state carried over from previous commands. If commands rely on a previous command to execute, you have to send them in a single statement, or as a script. If you want an interactive shell, there is the invoke_shell
command, but then you need to parse the shell output to simulate interactive use (the pexpect library can be used here).
You can use the sudo
command, or su -c
to execute the command.. However, I would suggest configuring a secure login for the needed user, and connecting as that user directly.
Related Topics
Is There a Simple Way to Remove Multiple Spaces in a String
CSS Not Loading Wrong Mime Type Django
Ignore Case in Glob() on Linux
How to Setup Environment Variable R_User to Use Rpy2 in Python
Python Linux Selenium: Chrome Not Reachable
Increasing a File's Size Using Mmap
Importerror: No Module Named Pytesseract
Python Detect Linux Shutdown and Run a Command Before Shutting Down
Multiple Kernels in Enthought Canopy
Difference Between 'Sorted(List)' VS 'List.Sort()'
Do Not Want the Images to Load and CSS to Render on Firefox in Selenium Webdriver - Python
Python Multiprocessing Memory Usage
Plotting the Data with Scrollable X (Time/Horizontal) Axis on Linux
How to Cleanly Kill Subprocesses in Python