【问题标题】:How to run a multi command Linux shell script from within R?如何从 R 中运行多命令 Linux shell 脚本?
【发布时间】:2018-06-25 18:12:53
【问题描述】:

我正在启动一个缺少所需驱动程序的 linux 虚拟环境,因此我使用 shell 进行安装。我正在手动执行此操作,但想从 R 中自动化它,我的其余代码都在其中。

我可以通过点击 Tools>Shell...在 R 中打开 shell...

然后我要运行多行 Bash 脚本以安装“ODBC Driver 17 for SQL Server”

sudo su 
curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
curl https://packages.microsoft.com/config/debian/8/prod.list > /etc/apt/sources.list.d/mssql-release.list

exit
sudo apt-get update
sudo ACCEPT_EULA=Y apt-get install msodbcsql17

我想将这些命令保存在某种可读文件中,然后在 R 中运行。

经过一番搜索,我看到了使用 System 运行单行的帖子,但我无法找到有关是否/如何将其扩展为运行多行或如何从某种方式中提取这些命令的信息保存的文件。

上下文:我是 linux 和 Bash/Shell 命令的新手 谢谢!

【问题讨论】:

  • 您可以使用;作为分隔符将所有命令链接到一行。
  • 谢谢@RalfStubner。当调用system("sudo su; whoami") 时,我得到username 而不是预期的root,因为我在shell 中使用连续命令会得到。同样,将代码与我上面的问题中的; 链接失败,因为权限未通过。我如何在与; 链接时保留权限?
  • 确实,sudo su 很特别。如果您调用 curl ...| sudo apt-key ...curl ...| sudo tee ... ,则不需要它。
  • 谢谢@RalfStubner。我不确定我是否完全理解你的答案。我认为这已成为own question。希望那里的答案将有助于澄清我自己和其他人。如果你有机会,我会喜欢你的意见。谢谢!

标签: r linux bash shell driver


【解决方案1】:

您可以使用; 分隔命令并将整个脚本存储为单个字符串。如果您的脚本中有特殊字符(目前没有),则必须非常小心正确使用转义字符。

对于你的 bash 脚本,这样的东西应该可以工作

command="sudo su ; 
curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -; 
curl https://packages.microsoft.com/config/debian/8/prod.list > /etc/apt/sources.list.d/mssql-release.list; 
exit;
sudo apt-get update;
sudo ACCEPT_EULA=Y apt-get install msodbcsql17;"

system(command)

另一种解决方法是将脚本保存为 .sh bash 脚本,然后在 command() 中调用脚本文件名。请注意,要使 bash 脚本可以从命令行执行,您必须在最顶部添加 she-bang 行 (#!/bin/bash)。

【讨论】:

  • 谢谢,很有帮助!由于没有来自sudo su 的权限,运行此代码给了我(23) Failed writing body 更多详细信息,请参阅我关于上述OP 权限的评论/问题。
  • 嗯,另一种解决方法是将您的脚本保存为 .sh bash 脚本,然后在 command() 中调用脚本文件名。请注意,要使 bash 脚本可执行,您必须在最顶部添加 she-bang 行 (#!/bin/bash)。或者只是按照上面戴夫的建议。
  • 所以我创建了一个 .sh bash 脚本并通过system(command = "./driver_load.sh") 调用它。我仍然收到同样的错误:ERROR: This command can only be used by root.(23) Failed writing body。这很奇怪,因为从 shell 中逐行运行相同的代码确实有效
  • 我已经打开another question 来解决这个问题。如果您编辑答案以包含您对执行脚本的见解,它会更好地回答原始问题,我可以接受您的回答
【解决方案2】:

其实多行命令就可以了:

command <- "cd
pwd
ls"
system(command)

MS 提供的命令的问题是(不必要的)使用su。您可以重写命令以仅在必要时使用提升的权限:

command="curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
curl https://packages.microsoft.com/config/debian/8/prod.list | sudo tee /etc/apt/sources.list.d/mssql-release.list
sudo apt-get update
sudo ACCEPT_EULA=Y apt-get install msodbcsql17"
system(command)

例如heresudo tee

【讨论】:

  • 这行得通,谢谢!只是为了增加这个解决方案,以防其他人看到正在寻找原始问题的答案,我看到我可以将这些命令保存在 bash 脚本中,例如load_driver.sh 然后用 R 的system(command = "./load_driver.sh") 调用它。在 R 中运行之前,不要忘记让这个文件在 bash 中可执行:chmod +x load_driver.sh
最近更新 更多