具体的问题如下图所示
前置条件:deployer 账号不能执行 sudo su- 切换为 root 用户,只能执行 sudo su 暂时获得 root 权限。
图一为手动在机器上执行巡检命令 先 sudo su 然后 supervisorctl status 正常返回结果。
用图二脚本中的语句 paramiko.SSHClient().exec_command('sudo su;supervisorctl status',get_pty=True) 执行,python 进程一直处于运行状态 但无返回结果。
命令行单独运行以下语句 也是同样的结果:
python -c 'import paramiko;ssh=paramiko.SSHClient();ssh.load_system_host_keys();ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy());ssh.connect("xxx",22,"deployer","xxx",compress=True);stdin,stdout,stderr = ssh.exec_command("sudo su;supervisorctl status");print stdout.read()'
怀疑是 sudo su 切换后环境变量仍然是 deployer ? 所以执行不成功??
求大佬指点
弄出 ssh.exec_command 的代码看看
[提升 python 脚本到 root 权限执行]( https://www.oschina.net/code/snippet_23734_23431)
sudo -i,加载用户变量,并跳转到目标用户 home 目录
sudo -s,不加载用户变量,不跳转目录
额== deployer 账号不能执行 sudo su- 切换为 root 用户,只能执行 sudo su 暂时获得 root 权限
https://github.com/paramiko/paramiko/blob/master/paramiko/client.py
中间有个 exec_command 函数--
试试这个,不确定行不行:
sudo su -l root -c "supervisorctl status"
完美解决-- 我就是不知道怎么把两条命令并为一行!!
引号里面用分号隔开多条命令?
sudo supervisorctl status 或者 sudo su - root sh -c 'supervisorctl status'
两条 shell 命令可以用 && 连接
你用 ssh 的话, 可以用 Fabric 库, 对 paramiko 和 invoke 的封装, 还可以用 Responder 对象做交互式响应,
只是别看 Fabric1 的文档, 看 Fabric2 的, 改动有点大
我就是用分号隔开 sudo su;supervisorctl status,不行,估计环境变量没跟进去-
可以试试
后面应该可以-
linux 文档很方便
$ su -h
用法:
su [选项] [-] [USER [参数]...]
将有效用户 id 和组 id 更改为 USER 的 id。
单个 - 视为 -l。如果未指定 USER,将假定为 root。
选项:
......
-, -l, --login 使 shell 成为登录 shell
-c, --command <命令> 使用 -c 向 shell 传递一条命令
--session-command <命令> 使用 -c 向 shell 传递一条命令
而不创建新会话
......
-V, --version 输出版本信息并退出
我来教楼主 2 招:
1 用 ssh+密钥+从远程 root 连接,即可绕过 用户,sudo 这种问题。
2 用 powershell 远程连接。即可比 python 简单。
对比:
$连接 1 = New-PSSession -HostName 1.1.1.1 -UserName root -KeyFilePath /tmp/a.b
invoke-command -ScriptBlock { supervisorctl status } -Session $连接 1
import paramiko;
ssh=paramiko.SSHClient();
ssh.load_system_host_keys();
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy());
ssh.connect("xxx",22,"deployer","xxx",compress=True);
stdin,stdout,stderr = ssh.exec_command("supervisorctl status");
print stdout.read()
主要我没 root 有 root 我肯定用 root--