在R中调用bash执行SCP传输命令时如何查看、捕获输出内容
问题根因
你之前尝试system("ls")能正常拿到输出,是因为这类常规命令的结果默认走标准输出流(stdout),R可以直接读取。
而SCP的文件传输列表、进度提示、交互确认信息,默认是输出到*标准错误流(stderr)*的——R原生的system()函数默认仅收集stdout的内容,完全不会捕获stderr的输出,这就是你运行SCP命令时拿不到预期结果、返回值为空的核心原因。
直接可用的解决方案
最简便的调整方式是在原有SCP命令的末尾加上流重定向参数2>&1,作用是把stderr的所有内容合并到stdout流里,R就能正常接收全部输出了。
代码调整示例
原有命令:
command_to_run <- "scp -r root@xx.xxx.xxx.xxx:~/path_to_dir/dir /Users/Me/.../target_path/"
修改为(追加重定向参数):
command_to_run <- "scp -r root@xx.xxx.xxx.xxx:~/path_to_dir/dir /Users/Me/.../target_path/ 2>&1"
根据你的使用场景选择对应执行方式:
- 如果需要实时在R控制台查看传输的文件列表、进度:直接调用系统命令即可,所有输出会实时打印在控制台
system(command_to_run) - 如果需要把传输日志存成R变量做后续处理:给
system()加上intern = TRUE参数,就能完整拿到所有输出内容transfer_log <- system(command_to_run, intern = TRUE) # 直接打印收集到的传输日志 print(transfer_log)
补充注意事项
- 加上
2>&1重定向后,SCP首次连接需要确认主机指纹、输入密码的交互式提示也能正常显示,不会出现R脚本卡在无提示等待的情况 - 如果需要更详细的传输调试日志,可以在SCP命令里加上
-v参数,所有详细日志也会通过重定向被正常捕获 - 如果不想手动做流重定向,也可以用R的
processx包跑外部命令,它可以独立捕获stdout和stderr流的内容,不需要额外调整shell命令
内容的提问来源于stack exchange,提问作者ulima2_
相关产品推荐
相关产品推荐

