2017-08-03 108 views
1

在我的工作中,訪問我們羣集的邊緣節點服務器每天都會重新實例化。這意味着我必須克隆我們的repo,並且每天早上安裝一堆R包。我寫了一個bash腳本(使用https://github.com/eddelbuettel/littler從命令行打開R)來自動執行此操作,並且除了一個打嗝外,它都可以工作。使用bash腳本安裝R包 - 對提示做出響應

巴什稱:這將打開R對話,並調用以下命令 [R install.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)我告訴它的庫編寫程序包中我已經試過這一點,而包沒去那裏,他們到達了空。沒有什麼是從回購實際下載的。

2)以某種方式讓腳本能夠在我需要的兩個肯定的響應中輸入,以便讓R完成它的任務並創建它自己的庫。

對這些任何建議的任何建議將不勝感激!

回答

0

一個不同的方法,工作比我最初發布好得多:

在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不會提示您,並且您的腳本將按預期運行。

1

有多種解決方案。我將展示兩個類似的解決方案。

交互腳本:

#!/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 
+0

所以這個問題實際上更多的是與「小問題」,我用來與R接口的軟件包。在你的例子中,通往test.sh的管道工作正常,但實際上我從內部運行R腳本shell腳本。由於某些原因,當我從命令行訪問它時,R似乎沒有給出提示。 –

0

兩個選項:

yes | r install.R 

或:

{ echo y; echo y; } | r install.R 
+0

事實證明,你實際上不能將管道連接到littler,正如這裏所建議的那樣。但我很欣賞這個想法。我最終只是在啓動R會話之前將必要的字符串打印到控制檯,以便我可以快速複製/粘貼一段代碼。兩步而不是一步,但優於十步。 –

0

注:這在技術上但是很笨拙並且容易出錯。請看我的其他答案。

我想出了一個辦法。

第一個,創建或修改.Rprofile。在該文件的頂部添加安裝和響應。例如:

repos = [CRAN or wherever you're sourcing from] 
install.packages(package1, repos) 
y 
y 
install.packages(package2, repos) 
install.packages(package3, repos) 
... # etc. 

'y'只適用於第一個包,當R詢問您是否要創建一個新庫時。隨後的軟件包也將被丟棄在那裏。

如果您確實希望它免提,並且腳本在安裝R軟件包後執行其他操作,您可以在末尾添加quit()語句,該語句將退出R並執行您希望腳本執行的任何操作。當你想要稍後啓動R時,這可能會很麻煩,所以你希望腳本能夠傳遞一些不同的.Rprofiles。

二,在你的bash腳本中,只需打開R與R。 .Rprofile將在啓動時立即運行,並且軟件包將自動下載。