我在python中通过ssh执行命令。
os.system("ssh atl.LB99@172.31.54.76 'bash --login -c "if [[ -e filepath && ! -L filepath ]];then mv filepath filepath.backup; fi;"'")
我有一个使用此命令执行的文件路径列表。这个scommand的目的是在原始文件名之后添加“.backup”。但是,这并不总是有效。文件名以结尾(可执行文件。不是文件名的一部分,只是说该文件是可执行文件),没有将其名称更改为“filename.backup”。这些文件确实具有足够的权限(例如,-rwxrwxr-x)。
系统是linux,shell是bash。
解决这个问题的关键是什么?
答案 0 :(得分:2)
没有错误和偶然的复杂性,这可能看起来像:
[Parallel(n_jobs=1)]: Done 1 out of 1 | elapsed: 7.4min remaining: 0.0s
building tree 2 of 5
[Parallel(n_jobs=1)]: Done 1 out of 1 | elapsed: 7.5min remaining: 0.0s
building tree 2 of 5
[Parallel(n_jobs=1)]: Done 1 out of 1 | elapsed: 7.5min remaining: 0.0s
building tree 2 of 5
[Parallel(n_jobs=1)]: Done 1 out of 1 | elapsed: 7.8min remaining: 0.0s
building tree 2 of 5
building tree 3 of 5
building tree 3 of 5
building tree 3 of 5
building tree 3 of 5
building tree 4 of 5
building tree 4 of 5
building tree 4 of 5
building tree 4 of 5
building tree 5 of 5
building tree 5 of 5
building tree 5 of 5
这里的关键点是什么?
import subprocess
try:
from pipes import quote # Python 2.x
except ImportError:
from shlex import quote # Python 3.x
# does not need to be shell-quoted; path='/path/to/filename with spaces' is legal
path = "filepath"
cmd = '''
path=%(path)s
# this is all POSIX-compliant syntax below, so we don't need to rely on bash
if [ ! -L "$path" ] && [ -e "$path" ]; then
mv -- "${path}" "$path.backup"
fi
''' % {"path": quote(path)}
subprocess.Popen(['ssh', 'atl.LB99@172.31.54.76', cmd])
或os.system()
参数用于shell=True
,所以没有本地shell。因为我们不使用subprocess.Popen()
,所以只有一个远程shell - 一个直接由ssh启动的shell,而不是由启动的另一个 壳。bash -c
在Python 2中逃避它。shlex.quote()
块需要以pipes.quote()
。 http://shellcheck.net/是此类验证的有用资源。