您可以使用ssh::ssh_exec_internal 和一些shell 命令来“查找”命令。
sess <- ssh::ssh_connect("r2@myth", passwd="...")
out <- ssh::ssh_exec_internal(sess, command = "find /home/r2/* -maxdepth 3 -type f -iname '*.log'")
str(out)
# List of 3
# $ status: int 0
# $ stdout: raw [1:70] 2f 68 6f 6d ...
# $ stderr: raw(0)
stdout/stderr 是原始的(远程命令没有产生 ascii 数据是可行的),所以我们可以使用rawToChar 进行转换。 (如果你有非 ASCII 数据,这可能不是控制台安全的,但它就在这里,所以我会用它。)
rawToChar(out$stdout)
# [1] "/home/r2/logs/dns.log\n/home/r2/logs/ping.log\n/home/r2/logs/status.log\n"
remote_files <- strsplit(rawToChar(out$stdout), "\n")[[1]]
remote_files
# [1] "/home/r2/logs/dns.log" "/home/r2/logs/ping.log" "/home/r2/logs/status.log"
对于下载,scp_download没有矢量化,所以我们一次只能上传一个文件。
for (rf in remote_files) ssh::scp_download(sess, files = rf, to = ".")
# 4339331 C:\Users\r2\.../dns.log
# 36741490 C:\Users\r2\.../ping.log
# 17619010 C:\Users\r2\.../status.log
对于上传,scp_upload 是矢量化的,所以我们可以一次性发送所有内容。我将创建一个新目录(仅用于此示例,并且不会完全弄乱我的远程服务器:-),然后上传它们。
ssh::ssh_exec_wait(sess, "mkdir '/home/r2/newlogs'")
# [1] 0
ssh::scp_upload(sess, files = basename(remote_files), to = "/home/r2/newlogs/")
# [100%] C:\Users\r2\...\dns.log
# [100%] C:\Users\r2\...\ping.log
# [100%] C:\Users\r2\...\status.log
# [1] "/home/r2/newlogs/"
(我觉得奇怪的是 scp_upload 是矢量化的,而 scp_download 不是。如果这是在 shell/终端上,那么对 scp 的每次调用都需要连接、验证、复制,然后断开连接,一个有点低效;因为我们使用的是保存的session,我相信(未验证)由于没有对 R 函数进行矢量化而几乎没有效率损失......尽管它仍然是 真的很容易对其进行矢量化。)