使用 bash 脚本安装 R 包 - 响应提示
Installing R packages with bash script - responding to prompts
在我的工作中,每天都会重新实例化访问我们集群的边缘节点服务器。这意味着我必须每天早上克隆我们的 repo 并安装一堆 R 包。我写了一个 bash 脚本(使用 https://github.com/eddelbuettel/littler 从命令行打开 R)来自动执行此操作,除了一个小问题外,它可以正常工作。
Bash 调用:
r install.R
打开 R 会话并调用以下命令:
repos <- "http://... [our CRAN equivalent]"
install.packages("[package_name]",repos)
现在,通常情况下,如果我自己在 R 中输入这个,我会得到这样的响应:
Installing package into ‘/usr/hdp/2.5.5.3-2/spark2/R/lib’ (as ‘lib’ is unspecified)
Warning in install.packages("[name_of_package]", repos = "http://...") :
'lib = "/usr/hdp/2.5.5.3-2/spark2/R/lib"' is not writable
Would you like to use a personal library instead? (y/n)
我会说 'y,',然后是另一个 'y',当它建议创建一个库时。但是,当我从 bash 脚本执行此操作时,它只是说库不可写并中止。
我在这里看到两个选项:
1) 我告诉它在哪个库中写入包。我试过了,虽然包确实去了那里,但它们是空的。实际上没有从 repo 下载任何内容。
2) 以某种方式让脚本能够输入我需要的两个肯定响应,以便让 R 执行它的操作并创建它自己的库。
如有任何建议,我们将不胜感激!
对此有多种解决方案。我将展示两个类似的解决方案。
交互脚本:
#!/bin/bash
# test.sh
printf "Response 1: "
read resp1
echo "You inserted $resp1"
printf "Response 2: "
read resp2
echo "You inserted $resp2"
要将两个条目通过管道传输到此脚本中,我们可以使用 here string:
$ ./test.sh <<< $'yes\nno\n'
Response 1: You inserted yes
Response 2: You inserted no
每个条目都由 \n 字符与其他条目分隔。该字符串被发送到脚本的标准输入。
或者,您也可以将字符串通过管道传输到脚本标准输入流中:
$ printf 'yes\nno\n' | ./test.sh
Response 1: You inserted yes
Response 2: You inserted no
两个选项:
yes | r install.R
或:
{ echo y; echo y; } | r install.R
注意: 这在技术上可行,但非常笨拙且容易出错。请看我的另一个回答
我想出了办法。
首先,创建或修改.Rprofile。在该文件的顶部添加安装和响应。例如:
repos = [CRAN or wherever you're sourcing from]
install.packages(package1, repos)
y
y
install.packages(package2, repos)
install.packages(package3, repos)
... # etc.
只有当 R 询问您是否要创建新库时,第一个包才需要“y”。后面的包也会丢进去
如果你真的想让它免提并且脚本在安装 R 包后做其他事情,你可以在最后添加一个 quit()
语句,这将退出 R 并做任何你想做的事情想要脚本做。当您想稍后启动 R 时,这可能会很烦人,因此您希望脚本传递几个不同的 .Rprofile。
其次, 在您的 bash 脚本中,只需使用 R
打开 R。 .Rprofile 将在启动时立即 运行,并且将自动下载包。
一种比我最初发布的方法效果更好的不同方法:
在bash中:
为安装创建特定的库(与默认 R 将要创建的库相同)
mkdir -p R/x86_64-pc-linux-gnu-library/3.3
Rscript --vanilla install_packages.R
在install_packages.R中:
pkg_list <- # however you want to get this
for (pkg in pkg_list) {
install.packages(pkg, repos = "your_cran_mirror",
lib = "R/x86_64-pc-linux-gnu-library/3.3")
if (!require(pkg, character.only = T)) {
quit(save = "no", status = 1, runLast = FALSE)
}
}
使用此方法,R 不会提示您,您的脚本将 运行 按预期进行。
在我的工作中,每天都会重新实例化访问我们集群的边缘节点服务器。这意味着我必须每天早上克隆我们的 repo 并安装一堆 R 包。我写了一个 bash 脚本(使用 https://github.com/eddelbuettel/littler 从命令行打开 R)来自动执行此操作,除了一个小问题外,它可以正常工作。
Bash 调用: r install.R
打开 R 会话并调用以下命令:
repos <- "http://... [our CRAN equivalent]"
install.packages("[package_name]",repos)
现在,通常情况下,如果我自己在 R 中输入这个,我会得到这样的响应:
Installing package into ‘/usr/hdp/2.5.5.3-2/spark2/R/lib’ (as ‘lib’ is unspecified)
Warning in install.packages("[name_of_package]", repos = "http://...") :
'lib = "/usr/hdp/2.5.5.3-2/spark2/R/lib"' is not writable
Would you like to use a personal library instead? (y/n)
我会说 'y,',然后是另一个 'y',当它建议创建一个库时。但是,当我从 bash 脚本执行此操作时,它只是说库不可写并中止。
我在这里看到两个选项: 1) 我告诉它在哪个库中写入包。我试过了,虽然包确实去了那里,但它们是空的。实际上没有从 repo 下载任何内容。
2) 以某种方式让脚本能够输入我需要的两个肯定响应,以便让 R 执行它的操作并创建它自己的库。
如有任何建议,我们将不胜感激!
对此有多种解决方案。我将展示两个类似的解决方案。
交互脚本:
#!/bin/bash
# test.sh
printf "Response 1: "
read resp1
echo "You inserted $resp1"
printf "Response 2: "
read resp2
echo "You inserted $resp2"
要将两个条目通过管道传输到此脚本中,我们可以使用 here string:
$ ./test.sh <<< $'yes\nno\n'
Response 1: You inserted yes
Response 2: You inserted no
每个条目都由 \n 字符与其他条目分隔。该字符串被发送到脚本的标准输入。
或者,您也可以将字符串通过管道传输到脚本标准输入流中:
$ printf 'yes\nno\n' | ./test.sh
Response 1: You inserted yes
Response 2: You inserted no
两个选项:
yes | r install.R
或:
{ echo y; echo y; } | r install.R
注意: 这在技术上可行,但非常笨拙且容易出错。请看我的另一个回答
我想出了办法。
首先,创建或修改.Rprofile。在该文件的顶部添加安装和响应。例如:
repos = [CRAN or wherever you're sourcing from]
install.packages(package1, repos)
y
y
install.packages(package2, repos)
install.packages(package3, repos)
... # etc.
只有当 R 询问您是否要创建新库时,第一个包才需要“y”。后面的包也会丢进去
如果你真的想让它免提并且脚本在安装 R 包后做其他事情,你可以在最后添加一个 quit()
语句,这将退出 R 并做任何你想做的事情想要脚本做。当您想稍后启动 R 时,这可能会很烦人,因此您希望脚本传递几个不同的 .Rprofile。
其次, 在您的 bash 脚本中,只需使用 R
打开 R。 .Rprofile 将在启动时立即 运行,并且将自动下载包。
一种比我最初发布的方法效果更好的不同方法:
在bash中:
为安装创建特定的库(与默认 R 将要创建的库相同)
mkdir -p R/x86_64-pc-linux-gnu-library/3.3
Rscript --vanilla install_packages.R
在install_packages.R中:
pkg_list <- # however you want to get this
for (pkg in pkg_list) {
install.packages(pkg, repos = "your_cran_mirror",
lib = "R/x86_64-pc-linux-gnu-library/3.3")
if (!require(pkg, character.only = T)) {
quit(save = "no", status = 1, runLast = FALSE)
}
}
使用此方法,R 不会提示您,您的脚本将 运行 按预期进行。