python 子进程远程查找 -exec 文件名 space
python subprocess remote find -exec filename with space
所以我有一个远程 Linux 服务器,我想 运行 我本地机器上的一个 Python 脚本列出特定文件夹中的所有文件及其修改日期远程服务器。到目前为止,这是我的代码:
command = "find \""+to_directory+'''\"* -type f -exec sh -c \"stat -c \'%y:%n\' \'{}\'\" \;'''
scp_process_ = subprocess.run("ssh "+to_user+"@"+to_host+" '"+command+"' ", shell=True, capture_output=False, text=True)
现在运行执行命令
find "/shares/Public/Datensicherung/"* -type f -exec sh -c "stat -c '%y:%n' '{}'" \;
在服务器本身上工作正常,没有任何错误。
但是,一旦我使用子进程通过 ssh 远程 运行 它,文件夹中的文件就会出现问题 spaces: "/shares/Public/Datensicherung/New [=26= .txt" 里面有 space:
stat: can't stat '/shares/Public/Datensicherung/New': No such file or directory
stat: can't stat 'folder/hi.txt': No such file or directory
我知道它搞砸了,但这是我可以构建的最佳解决方案。
我想坚持使用 subprocess 和 ssh,但如果您有更好的解决方案,请随时 post 它。
有时问题的发生是因为命令字符串格式错误。出于与 Unix 通信的目的,shell 被创建 shlex module. So basically you wrap your code with shlex,然后将其传递给 supbrocess.run
。
我没有看到要调用的实际最终命令,但您可以自己使用 shlex.split
将其拆分为正确的命令。
根据你的例子,它会是这样的:
from shlex import join
cmd = join(['ssh',
f'{to_user}@{to_host}',
'find',
f'{to_directory}*',
'-type',
'f',
'-exec',
'sh',
'-c',
"stat -c '%y:%n' '{}'",
';']))
scp_process_ = subprocess.run(cmd, shell=True, capture_output=False, text=True)
此外,您可能想尝试一下 shell=True
选项。
使用 shell=True
您将调用 三个 shell 个实例,每个实例都需要一层引用。当然,这是可能的,但如果可能的话,有很多理由要避免它。
首先,您可以轻松避免本地 shell=True
,这实际上提高了 Python 代码的稳健性和清晰度。
command = "find \""+to_directory+'''\"* -type f -exec sh -c \"stat -c \'%y:%n\' \'{}\'\" \;'''
scp_process_ = subprocess.run(
["ssh", to_user+"@"+to_host, command],
capture_output=False, text=True)
其次,stat
可以很容易地接受多个参数,所以你也可以去掉sh -c '...'
。
command = 'find "' + to_directory + '" -type f -exec stat -c "%y:%n" {} +'
优化还会将 +
切换为 \;
(因此 sh -c ''
包装器无论如何都是无用的)。
所以我有一个远程 Linux 服务器,我想 运行 我本地机器上的一个 Python 脚本列出特定文件夹中的所有文件及其修改日期远程服务器。到目前为止,这是我的代码:
command = "find \""+to_directory+'''\"* -type f -exec sh -c \"stat -c \'%y:%n\' \'{}\'\" \;'''
scp_process_ = subprocess.run("ssh "+to_user+"@"+to_host+" '"+command+"' ", shell=True, capture_output=False, text=True)
现在运行执行命令
find "/shares/Public/Datensicherung/"* -type f -exec sh -c "stat -c '%y:%n' '{}'" \;
在服务器本身上工作正常,没有任何错误。
但是,一旦我使用子进程通过 ssh 远程 运行 它,文件夹中的文件就会出现问题 spaces: "/shares/Public/Datensicherung/New [=26= .txt" 里面有 space:
stat: can't stat '/shares/Public/Datensicherung/New': No such file or directory
stat: can't stat 'folder/hi.txt': No such file or directory
我知道它搞砸了,但这是我可以构建的最佳解决方案。 我想坚持使用 subprocess 和 ssh,但如果您有更好的解决方案,请随时 post 它。
有时问题的发生是因为命令字符串格式错误。出于与 Unix 通信的目的,shell 被创建 shlex module. So basically you wrap your code with shlex,然后将其传递给 supbrocess.run
。
我没有看到要调用的实际最终命令,但您可以自己使用 shlex.split
将其拆分为正确的命令。
根据你的例子,它会是这样的:
from shlex import join
cmd = join(['ssh',
f'{to_user}@{to_host}',
'find',
f'{to_directory}*',
'-type',
'f',
'-exec',
'sh',
'-c',
"stat -c '%y:%n' '{}'",
';']))
scp_process_ = subprocess.run(cmd, shell=True, capture_output=False, text=True)
此外,您可能想尝试一下 shell=True
选项。
使用 shell=True
您将调用 三个 shell 个实例,每个实例都需要一层引用。当然,这是可能的,但如果可能的话,有很多理由要避免它。
首先,您可以轻松避免本地 shell=True
,这实际上提高了 Python 代码的稳健性和清晰度。
command = "find \""+to_directory+'''\"* -type f -exec sh -c \"stat -c \'%y:%n\' \'{}\'\" \;'''
scp_process_ = subprocess.run(
["ssh", to_user+"@"+to_host, command],
capture_output=False, text=True)
其次,stat
可以很容易地接受多个参数,所以你也可以去掉sh -c '...'
。
command = 'find "' + to_directory + '" -type f -exec stat -c "%y:%n" {} +'
优化还会将 +
切换为 \;
(因此 sh -c ''
包装器无论如何都是无用的)。