如何使用Fabric检查远程目录是否包含内容?
如何通过Fabric检测远程Ubuntu系统的文件夹是否包含内容
问题背景
我使用Fabric在远程Ubuntu机器上运行Python脚本,需执行文件夹清理任务。目标文件夹为/test/folder/,常规清理命令rm -r /test/folder/*在文件夹为空时会执行失败,因此需要先检测文件夹是否包含可删除内容。
我尝试用以下Bash命令做检测:
test -n "$(find /test/folder/ -prune -empty)"
该命令在目录为空时返回退出码0,存在内容时返回退出码1。但通过Fabric执行时,只要命令返回非零退出码,Fabric就会直接抛出异常退出,错误信息如下:
invoke.exceptions.UnexpectedExit: Encountered a bad command exit code! Command: 'test -n "$(find /path/to/target/folder/ -prune -empty)"' Exit code: 1 Stdout: Stderr:
核心需求是解决远程目录内容的检测问题,底层清理任务为次要需求。
解决方案
方法1:允许非零退出码,手动判断结果
Fabric的run方法默认会在命令返回非零码时抛出UnexpectedExit异常,可通过warn=True参数禁用此行为,之后通过返回结果的exited属性判断退出码:
import fabric target = '/path/to/target/folder/' with fabric.Connection('Remote') as remote: # 执行检测命令,允许非零退出码 result = remote.run(f'test -n "$(find {target} -prune -empty)"', hide=True, warn=True) # 目录为空时exit code为0,有内容时为1 is_empty = result.exited == 0 has_files = not is_empty
方法2:调整Bash命令,统一返回0退出码
修改命令逻辑,让无论目录是否为空都返回0退出码,通过输出内容判断结果:
import fabric target = '/path/to/target/folder/' with fabric.Connection('Remote') as remote: # 通过echo输出状态,确保命令始终返回0 result = remote.run(f'if test -n "$(find {target} -prune -empty)"; then echo "empty"; else echo "has_files"; fi', hide=True) has_files = result.stdout.strip() == 'has_files'
方法3:改用更直观的ls -A命令检测
使用ls -A命令(列出除.和..外的所有文件),空目录时输出为空,通过判断输出是否为空来检测:
import fabric target = '/path/to/target/folder/' with fabric.Connection('Remote') as remote: # 执行ls -A,允许非零退出码(空目录时ls -A不会报错,此处warn=True可选) result = remote.run(f'ls -A {target}', hide=True, warn=True) # 输出非空则表示目录有内容 has_files = bool(result.stdout.strip())
此方法逻辑更直观,且ls -A在Ubuntu系统中默认支持,无需额外依赖。
内容的提问来源于stack exchange,提问作者Darien Marks
相关产品推荐
相关产品推荐

