通过paramiko按用户名而非UID更改文件所有者

1 投票
2 回答
1255 浏览
提问于 2025-04-18 17:15

我需要在远程服务器上对某个文件运行 chown 命令,以更改文件的拥有者(不是组)。paramiko 的 chown 命令需要三个参数:路径、组 ID(gid)和用户 ID(uid)。

在我的代码中,我有用户名,但没有用户 ID。所以这是我的代码:

#some code here
...
object_stat = sftp_client.stat(object_path)
sftp_client.chown(object_path, owner_username, int(object_stat.st_gid))
...
#more code

有没有办法解决这个问题?如果能避免使用 shell 命令,那就更好了。

谢谢!

2 个回答

0

这是来自未来的一个回答,专门给那些想了解这个问题的人。你可以使用SFTP客户端来发送任意的SSH命令,也就是说,

def sendCommand(sftp, *command, **kwargs):
  cmd = " ".join([str(c) for c in command])

  session = sftp.sock.get_transport().open_channel(kind = "session")

  try:
    session.exec_command(cmd)

    stdout = bytearray()
    stderr = bytearray()
    rc = 0 

    while True:
      if session.exit_status_ready():
        while True:
          data = session.recv(8192)
          if not data:
            break
          stdout.extend(data)
        while True:
          data = session.recv_stderr(8192)
          if not data:
            break
          stderr.extend(data)
        break

    rc = session.recv_exit_status()

    if rc != 0 and not kwargs.get("ignore_errors", False):
      raise ValueError("Command {0} failed with exit code {1}.\n{2}".format(" ".join(command), rc, stderr))
    else:
      try:
        return stdout.decode("UTF-8")
      except UnicodeDecodeError:
        return stdout
  finally:
    session.close()

然后,利用这个,我们可以通过通道运行 getent。当你对 passwd 数据库运行这个命令时,你会得到类似 root:x:0:0:root:/root:/bin/bash 的结果。这里的索引2是用户的UID,索引3是用户的GID(注意,这里说的是用户的GID,而不是某个任意组名的GID)。

uid = sendCommand(client, "getent", "passwd", username).split(":")[2]

对于组,你可以做同样的事情,但要使用 group 数据库。

gid = sendCommand(client, "getent", "group", group).split(":")[2]

getent 也可以接受UID或GID,这样你就可以反向查找。请注意,我这里主要是指POSIX主机,其他系统可能会有所不同。

0
  import pexpect
  new_child=pexpect.spawn("ssh ....")
  new_child.expect("Password:")
  new_child.sendline(mypass)
  new_child.expect("$")#or whatever the bash symbol is 
  new_child.sendline("chown. ...")
  new_chile.expect("$")

如果你想要输出结果,可以使用 new_child.before。

撰写回答