Как процитировать часть списка subprocess.run? - PullRequest
0 голосов
/ 07 ноября 2019

Мне нужно процитировать часть строки rsync, которую использует subprocess.run, которая содержит параметры ssh, к сожалению, пока что ничего из того, что я пробовал, не сработало.

Может кто-нибудь посоветовать мне, как правильно процитироватьпараметры ssh, чтобы он работал под rsync.

Сначала у меня был список списков, которые были переданы в subprocess.run, который завершается ошибкой:

Traceback (most recent call last):
  File "./tmp.py", line 20, in <module>
    process = subprocess.run(rsync_cmd, stderr=subprocess.PIPE)
  File "/usr/lib/python3.6/subprocess.py", line 423, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/usr/lib/python3.6/subprocess.py", line 729, in __init__
    restore_signals, start_new_session)
  File "/usr/lib/python3.6/subprocess.py", line 1295, in _execute_child
    restore_signals, start_new_session, preexec_fn)
TypeError: expected str, bytes or os.PathLike object, not list

Свести его вобычный список:

Unexpected remote arg: example.com:/var/log/maillog
rsync error: syntax or usage error (code 1) at main.c(1361) [sender=3.1.2]

Это имеет смысл, поскольку часть командной строки для rsync должна быть заключена в кавычки.

Поэтому я пытаюсь процитировать его:

rsync: Failed to exec /usr/bin/ssh -F /home/rspencer/.ssh/config -o PreferredAuthentications=publickey -o StrictHostKeyChecking=accept-new -o TCPKeepAlive=yes -o ServerAliveInterval=5 -o ServerAliveCountMax=24 -o ConnectTimeout=30 -o ExitOnForwardFailure=yes -o ControlMaster=autoask -o ControlPath=/run/user/1000/foo-ssh-master-%C -l root -p 234 -o Compression=yes: No such file or directory (2)
rsync error: error in IPC code (code 14) at pipe.c(85) [Receiver=3.1.2]
rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
rsync error: error in IPC code (code 14) at io.c(235) [Receiver=3.1.2]

Что связано, я ожидаю, с тем, что это строка вместо списка. Хотя я предполагаю, и это не имеет для меня полного смысла.

Обобщенный код моей последней попытки:

#!/usr/bin/python3

import subprocess

ssh_args = [
    "-F",
    "/home/rspencer/.ssh/config",
    "-o",
    "PreferredAuthentications=publickey",
    "-o",
    "StrictHostKeyChecking=accept-new",
    "-o",
    "TCPKeepAlive=yes",
    "-o",
    "ServerAliveInterval=5",
    "-o",
    "ServerAliveCountMax=24",
    "-o",
    "ConnectTimeout=30",
    "-o",
    "ExitOnForwardFailure=yes",
    "-o",
    "ControlMaster=autoask",
    "-o",
    "ControlPath=/run/user/1000/foo-ssh-master-%C",
    "-l",
    "root",
    "-p",
    "234",
]
rsync_params = []
src = "example.com:/var/log/maillog"
dest = "."

# Build SSH command
ssh_cmd = ["/usr/bin/ssh"] + ssh_args

# Use basic compression
ssh_cmd.extend(["-o", "Compression=yes"])

ssh_cmd = " ".join(ssh_cmd)
ssh_cmd = f'"{ssh_cmd}"'

# Build rsync command
rsync_cmd = ["/usr/bin/rsync", "-vP", "-e", ssh_cmd] + rsync_params + [src, dest]

# Run rsync
process = subprocess.run(rsync_cmd, stderr=subprocess.PIPE)

if process.returncode != 0:
    print(process.stderr.decode("UTF-8").strip())

Как будет выглядеть правильная команда в командной строке:

/usr/bin/rsync -vP -e "/usr/bin/ssh -F /home/rspencer/.ssh/config -o \
PreferredAuthentications=publickey -o StrictHostKeyChecking=accept-new -o \
TCPKeepAlive=yes -o ServerAliveInterval=5 -o ServerAliveCountMax=24 -o \
ConnectTimeout=30 -o ExitOnForwardFailure=yes -o ControlMaster=autoask \
-o ControlPath=/run/user/1000/foo-ssh-master-%C -l root -p 234 -o \
Compression=yes" example.com:/var/log/maillog .

1 Ответ

0 голосов
/ 07 ноября 2019

Оказывается, хитрость заключается в том, чтобы не пытаться заключить его в кавычки.

Я удалил следующую строку, и она работала без дальнейшей модификации:

ssh_cmd = f'"{ssh_cmd}"'

Я прочитал так много документации ипропустил, пока не задал вопрос. Мерфи.

Перечитывание поста " Как не приводить аргументы в подпроцессе? " и, наконец, понимание того, что говорил Грег Хьюгилл, помогло мне. Я виню в недостатке сна.

"Если вы используете кавычки в командной строке оболочки, то поместите все содержимое в один элемент args (без кавычек). ..." - Грег Хьюгилл

...