带有 RCurl 的 sftp 协议 - 最后一步,如何将 R 路径从 usr/lib 更改为 usr/local/lib

Posted

技术标签:

【中文标题】带有 RCurl 的 sftp 协议 - 最后一步,如何将 R 路径从 usr/lib 更改为 usr/local/lib【英文标题】:sftp protocol with RCurl - last step, how to change R path to libcurl from usr/lib to usr/local/lib 【发布时间】:2017-09-29 05:45:11 【问题描述】:

首先 - 我知道这不是一个特定的代码问题,所以请随时投票结束这个问题,但我今天大部分时间都在努力解决这个问题,并且可以使用一些帮助.我也认为这个线程可以帮助任何试图让 sftp 协议在 R 中工作的人,因为我将分享我今天所做的事情。

我一直在尝试更新 RCurl,使其支持 sftp 协议。在 R 中,我的协议看起来是这样的(版本和主机也是如此):

> library(RCurl)
> curlVersion()$protocols
 [1] "dict"   "file"   "ftp"    "ftps"   "gopher" "http"   "https"  "imap"   "imaps"  "ldap"   "ldaps"  "pop3"   "pop3s"  "rtsp"   "smb"    "smbs"  
[17] "smtp"   "smtps"  "telnet" "tftp" 

> curlVersion()$version
[1] "7.43.0"

> curlVersion()$host
[1] "x86_64-apple-darwin15.0"

不太好 - 没有 sftp 选项...

我按照这个线程 - http://andrewberls.com/blog/post/adding-sftp-support-to-curl - 更新了我机器上的 curl,并且部分成功。成功部分反映在我在命令行中运行以下命令时:

curl -V 
curl 7.55.1 (x86_64-apple-darwin15.6.0) libcurl/7.55.1 zlib/1.2.5 
libssh2/1.8.0
Release-Date: 2017-08-14
Protocols: dict file ftp gopher http imap ldap ldaps pop3 rtsp scp sftp smtp telnet tftp 
Features: AsynchDNS IPv6 Largefile libz UnixSockets 

这很好,因为我已经更新了 curl。但是,当我在 R 中加载 RCurl 并运行 curlVersion() 时,它没有更新。我检查了我的 /usr/ 目录的 lib 文件夹并遇到以下问题。在我的 /usr/lib 和 /usr/local/lib 中,都存在 libcurl 文件。具体来说:

/usr/lib 中的 libcurl.3.dylib、libcurl.4.dylib 和 libcurl.dylib /usr/local/lib 中的 libcurl.4.dylib、libcurl.dylib、libcurl.a 和 libcurl.la

我的 /usr/local/lib 目录中的文件是我想要使用的新文件,但是这里是我最头疼的地方。我将 /usr/local/lib 中的四个文件复制到 /usr/lib 中,然后我的电脑坏了。我的许多应用程序停止加载,我不得不重新安装我的 OS X,因为害怕搞砸其他任何东西。当我重新安装我的 OS X 时,它会将我的文件放回各自的文件夹中(它们在上面的项目符号中看起来如何)。

如果我不得不猜测,我可能不应该移动 .a 或 .la 文件...我不确定。

最后一件事 - 当我在控制台中运行 $ $PATH 时,我得到:

$PATH
-bash: /Users/Home/.rvm/gems/ruby-2.3.3/bin:/Users/Home/.rvm/gems/ruby-2.3.3@global/bin:/Users/Home/.rvm/rubies/ruby-2.3.3/bin:/Users/Home/anaconda2/bin:/usr/local/git/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Library/TeX/texbin:/Users/Home/.rvm/bin: No such file or directory

/usr/local/bin 在 /usr/bin 之前。但我没有看到 /usr/local/lib 或 /usr/lib 的任何内容 - 我可以将这些 (/usr/local/lib) 添加到我的路径中来解决这个问题吗? R 中的 .libPaths() 给了我这个:

.libPaths()
"/Library/Frameworks/R.framework/Versions/3.4/Resources/library"

...如果有帮助的话

编辑 - 我应该注意所有问题的根源,当然,因为 'sftp' 没有列在 R 的 curlVersion()$protocols 中,所以当我运行 RCurl::getURL() 或 RCurl:: ftpUpload()(我希望使用 ftpUpload),我收到错误:

> RCurl::ftpUpload(what = 'myfile.txt', to = 'sftp://userid:userpw@ip/'myfile.txt')
Error in function (type, msg, asError = TRUE)  : 
  Protocol "sftp" not supported or disabled in libcurl

谢谢!

【问题讨论】:

【参考方案1】:

呸!终于在带有 rstudio-server 的 Ubuntu 14.04 docker 容器中完成了这个工作。我遇到了每一个问题!但是我不得不花更多的时间来寻找所有这些东西,所以试图把它们放在一个地方,以便其他有这个问题的人这就是我所做的......

在linux终端中:

apt-get install libcurl4-openssl-dev

wget libssh2 and then compile with ordinary

./configure

make

make install

wget curl and then compile

./configure --with-sshlib2=/usr/local

make

make install

如果您需要 curl 使用 sftp 在终端中工作,此时可能仍然不需要。使用您刚刚安装的新 libcurl.so.4 对其进行验证。您刚刚安装的 curl 将安装到 /usr/local/bin 中,因此请使用 ldd 验证它是否使用旧库。我的使用的是旧的 libcurl,所以我将旧的 libcurl 链接到 /usr/local/lib 中的新 libcurl,然后重新编译 curl。

如果您希望 RCurl 正常工作,请将所有新库从 /usr/local/lib(libcurl 和 libssh2)复制到 /lib,然后移至 R 控制台。

在 Rconsole 中:

install.packages("RCurl", type = "source")

验证 sftp 协议是否启用

libcurlVersion() RCurl::curlVersion()

这些应该分别显示为 libcurl 和 RCurl 启用的协议。为 sftp 交叉手指!

以防万一,我也做了这些可能没多大作用的事情,但我在碰壁时做了,只是保持在原地。

升级的 R 和 R 工作室服务器

在重新安装 RCurl 之前删除了 curl 和 RCurl 的 R 版本。同样在较新的 rstudio 中,我不确定是否需要 type="source"。

正如 Canovice 所指出的,在 libcurl 和 libssh 库中移动时要小心。我打破了几次网络,幸运的是,因为它是一个我刚刚重新启动的 docker 容器。我发现一次移动所有东西效果最好,

cp /usr/local/lib/libssh* /lib && cp /usr/local/lib/libcurl* /lib

还应注意,我是一个完全的 R 新手,因此可能有比在整个地方移动库更清洁的方法。我尝试在 rstudio 中使用.libaths(),但最终放弃了。

【讨论】:

在 ./configure 之前,我必须运行 autoconf,但您的解决方案对我有用,谢谢! 我也坚持这一点,使用 curl -V 正确列出了 sftp,但无法让 R 使用它。有什么建议吗?【参考方案2】:

在实践中,我发现尝试更新现有的 curlopenssl 安装比安装全新版本并更新将使用它们的 PATH 环境更危险

在我的情况下,我较新的 curlopenssl 安装了 sftp 支持

/usr/local/opt/curl-openssl/bin
/usr/local/opt/openssl/lib/

因此我需要设置以下 envars

PATH="/usr/local/opt/curl-openssl/bin:$PATH"
LIBRARY_PATH="/usr/local/opt/openssl/lib/:$LIBRARY_PATH"

执行前

install.packages("RCurl", type="source")

【讨论】:

【参考方案3】:

从源代码安装 RCurl 对我有用!

install.packages("RCurl", type="source")

我在这里找到了解决方案 - http://www.omegahat.net/RCurl/FAQ.html - 特别是以下几行。

“我不能在 RCurl 中使用 scp 或 sftp,但 curl 的文档似乎表明它可以。那么为什么 RCurl 不支持它?

RCurl 确实支持它,但可能的问题是您安装的 libcurl 版本不支持它。您可以通过命令 curlVersion 检查您的 libcurl 以及 RCurl 支持的协议。如果 scp 和 sftp 不存在,请重新安装 libcurl,但支持使用 libssh2。在安装 libcurl 之前,您需要安装 libssh2 开发库和头文件。在某些操作系统上,您需要从源代码重建 RCurl。”

总的来说,这是对我的问题从头到尾的一个很好的总结。如果您的 RCurl 版本不支持 sftp,您需要先安装(在命令行)libssh2,然后重新安装 libcurl,然后出于某种原因从源代码重建。

【讨论】:

以上是关于带有 RCurl 的 sftp 协议 - 最后一步,如何将 R 路径从 usr/lib 更改为 usr/local/lib的主要内容,如果未能解决你的问题,请参考以下文章

CentOS 7 配置SFTP

xshell 5中文破

如果服务器不允许SSH连接,可以扭曲SFTP客户端吗?

python实现ssh及sftp功能

SFTP是什么协议?优势有哪些?与FTP有什么不同?

SFTP是什么协议?优势有哪些?与FTP有什么不同?