ana*_*chy 1 python regex ssh os.system sed
我试图在 python 脚本中运行一个 ssh 命令,使用和在远程服务器中完全匹配的字符串的末尾os.system添加一个。0sshsed
我有一个nodelist在远程服务器中调用的文件,它是一个看起来像这样的列表。
test-node-1
test-node-2
...
test-node-11
test-node-12
test-node-13
...
test-node-21
Run Code Online (Sandbox Code Playgroud)
我想使用 sed 进行以下修改,我想搜索test-node-1,当找到完全匹配时,我想在最后添加一个 0,文件最终必须是这样的。
test-node-1 0
test-node-2
...
test-node-11
test-node-12
test-node-13
...
test-node-21
Run Code Online (Sandbox Code Playgroud)
但是,当我运行第一个命令时,
hostname = 'test-node-1'
function = 'nodelist'
os.system(f"ssh -i ~/.ssh/my-ssh-key username@serverlocation \"sed -i '/{hostname}/s/$/ 0/' ~/{function}.txt\"")
Run Code Online (Sandbox Code Playgroud)
结果变成这样,
test-node-1 0
test-node-2
...
test-node-11 0
test-node-12 0
test-node-13 0
...
test-node-21
Run Code Online (Sandbox Code Playgroud)
我尝试在这样的命令中添加一个 \b,
os.system(f"ssh -i ~/.ssh/my-ssh-key username@serverlocation \"sed -i '/\b{hostname}\b/s/$/ 0/' ~/{function}.txt\"")
Run Code Online (Sandbox Code Playgroud)
该命令根本不起作用。
我必须手动输入节点名称,而不是像这样使用变量,
os.system(f"ssh -i ~/.ssh/my-ssh-key username@serverlocation \"sed -i '/\btest-node-1\b/s/$/ 0/' ~/{function}.txt\"")
Run Code Online (Sandbox Code Playgroud)
使我的命令工作。
我的命令有什么问题,为什么我不能做我想让它做的事?
此代码存在严重的安全问题;修复它们需要从头开始重新设计。让我们在这里这样做:
#!/usr/bin/env python3
import os.path
import shlex # note, quote is only here in Python 3.x; in 2.x it was in the pipes module
import subprocess
import sys
# can set these from a loop if you choose, of course
username = "whoever"
serverlocation = "whereever"
hostname = 'test-node-1'
function = 'somename'
desired_cmd = ['sed', '-i',
f'/\\b{hostname}\\b/s/$/ 0/',
f'{function}.txt']
desired_cmd_str = ' '.join(shlex.quote(word) for word in desired_cmd)
print(f"Remote command: {desired_cmd_str}", file=sys.stderr)
# could just pass the below direct to subprocess.run, but let's log what we're doing:
ssh_cmd = ['ssh', '-i', os.path.expanduser('~/.ssh/my-ssh-key'),
f"{username}@{serverlocation}", desired_cmd_str]
ssh_cmd_str = ' '.join(shlex.quote(word) for word in ssh_cmd)
print(f"Local command: {ssh_cmd_str}", file=sys.stderr) # log equivalent shell command
subprocess.run(ssh_cmd) # but locally, run without a shell
Run Code Online (Sandbox Code Playgroud)
如果你运行这个(除了subprocess.run最后,它需要一个真正的 SSH 密钥、主机名等),输出看起来像:
#!/usr/bin/env python3
import os.path
import shlex # note, quote is only here in Python 3.x; in 2.x it was in the pipes module
import subprocess
import sys
# can set these from a loop if you choose, of course
username = "whoever"
serverlocation = "whereever"
hostname = 'test-node-1'
function = 'somename'
desired_cmd = ['sed', '-i',
f'/\\b{hostname}\\b/s/$/ 0/',
f'{function}.txt']
desired_cmd_str = ' '.join(shlex.quote(word) for word in desired_cmd)
print(f"Remote command: {desired_cmd_str}", file=sys.stderr)
# could just pass the below direct to subprocess.run, but let's log what we're doing:
ssh_cmd = ['ssh', '-i', os.path.expanduser('~/.ssh/my-ssh-key'),
f"{username}@{serverlocation}", desired_cmd_str]
ssh_cmd_str = ' '.join(shlex.quote(word) for word in ssh_cmd)
print(f"Local command: {ssh_cmd_str}", file=sys.stderr) # log equivalent shell command
subprocess.run(ssh_cmd) # but locally, run without a shell
Run Code Online (Sandbox Code Playgroud)
这是正确/所需的输出;有趣的'"'"'习语是如何安全地在符合 POSIX 的 shell 中的单引号字符串中注入文字单引号。
有什么不同?批次:
~到远程服务器:它是多余和不必要的,因为它~是 SSH 会话开始的默认位置;以及我们正在使用的安全预防措施(以防止值被 shell 解析为代码)防止它产生任何影响(因为替换为~的活动值HOME不是由sed它自己完成的,而是由调用它的 shell完成的; 因为我们根本没有调用任何本地 shell,所以我们还需要使用os.path.expanduser来使~in~/.ssh/my-ssh-key受到尊重)。\b以确保它们被 Python 视为文字而不是语法。| 归档时间: |
|
| 查看次数: |
255 次 |
| 最近记录: |