如何用Paramiko SSHClient实现sudo su - diffuser切换用户执行命令?
Absolutely, you can simulate this exact workflow with Paramiko's SSHClient—let’s break down the two main approaches depending on whether you need to run a single command or multiple commands in the diffuser user’s session.
Solution 1: Run a Single Command Directly
If you only need to execute one command as diffuser, you can skip the full interactive shell switch and use sudo su - diffuser -c to run the command directly in their login shell (this matches the environment you get when running sudo su - diffuser locally).
Here’s a code example:
import paramiko # Set up the SSH connection ssh_client = paramiko.SSHClient() ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh_client.connect( hostname="your_target_host", username="your_initial_user", password="your_initial_password" ) # Define the command: switch to diffuser and run your target command target_command = "echo $USER && your_actual_command_here" full_command = f"sudo su - diffuser -c '{target_command}'" # Execute the command stdin, stdout, stderr = ssh_client.exec_command(full_command) # If your initial user requires a sudo password, send it here # Skip this block if sudo is passwordless for your user stdin.write("your_sudo_password\n") stdin.flush() # Read and print the output print("Command Output:") print(stdout.read().decode("utf-8")) # Handle any errors error_output = stderr.read().decode("utf-8") if error_output: print("\nError:") print(error_output) # Clean up the connection ssh_client.close()
Solution 2: Interactive Session for Multiple Commands
If you need to run several commands sequentially as diffuser (just like you would in a local CLI), use invoke_shell() to create a persistent interactive session. This lets you simulate typing commands step-by-step.
Example code:
import paramiko import time # Set up SSH connection ssh_client = paramiko.SSHClient() ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh_client.connect( hostname="your_target_host", username="your_initial_user", password="your_initial_password" ) # Start an interactive shell session shell = ssh_client.invoke_shell() shell.settimeout(10) # Wait for the initial prompt to appear (adjust sleep time if needed) time.sleep(1) initial_output = shell.recv(4096).decode("utf-8") print("Initial Prompt:\n", initial_output) # Send the sudo su command to switch to diffuser shell.send("sudo su - diffuser\n") time.sleep(1) su_output = shell.recv(4096).decode("utf-8") print("\nAfter sudo su -:\n", su_output) # Send sudo password if prompted if "password:" in su_output.lower(): shell.send("your_sudo_password\n") time.sleep(1) post_password_output = shell.recv(4096).decode("utf-8") print("\nAfter entering password:\n", post_password_output) # Now run commands as diffuser shell.send("echo $USER\n") time.sleep(1) user_output = shell.recv(4096).decode("utf-8") print("\nCurrent User:\n", user_output) # Run another example command shell.send("ls -l ~\n") time.sleep(1) ls_output = shell.recv(4096).decode("utf-8") print("\nHome Directory Contents:\n", ls_output) # Exit the diffuser session and close the connection shell.send("exit\n") time.sleep(1) ssh_client.close()
Key Notes to Keep in Mind
- Environment Matching: Using
sudo su - diffuser(with the hyphen) loadsdiffuser's full login environment, which is different from justsudo -u diffuser(which doesn't load their shell profile). Stick with the-to match your local workflow. - Sudo Permissions: Make sure your initial user has the right sudo privileges to switch to
diffuser—check the/etc/sudoersfile if you run into permission errors. - Prompt Handling: The
time.sleep()calls are a simple way to wait for the system to respond. For more reliability, you can loop until you detect a specific prompt (e.g.,diffuser@host:~$) instead of using fixed sleep times. - Encoding: Adjust the
decode("utf-8")part if your target system uses a different character encoding.
内容的提问来源于stack exchange,提问作者TNTimmy

