为什么我的bash无法执行R脚本?

时间:2010-01-11 23:29:16

标签: bash shell scripting r rscript

我的脚本使用对mysql的访问来获取启动Rscript的命令参数。 它的用法如下:Rscript $ RFILE $ ARGUMENTS(RFILE对应于Rscript的路径,ARGUMENTS对应于使用的路径文件和agr)。

我以不同的方式尝试,但我仍然有错误,这里是我的bash脚本的副本:

#!/usr/bin/env bash
# Execute R process
# -----------------
### Mysql Setup ###
USER=...
PASS=...
HOST=...
DB=...

# Get Job ID process
# Use to retrieve args in my DB
ID=$1

# Get script name
RFILE=$(mysql -u$USER -p$PASS -e "SELECT script_name FROM JobProcess WHERE script_run_id=$ID;" $DB)
SUBSTRING="script_name"
RFILE="${RFILE//$SUBSTRING}"

# Get script_args
ARGUMENTS=$(mysql -u$USER -p$PASS -e "SELECT script_args FROM JobProcess WHERE script_run_id=$ID;" $DB)
SUBSTRING2="script_args"
ARGUMENTS="${ARGUMENTS//$SUBSTRING2}"

RUN="Rscript $RFILE $ARGUMENTS"

# Try Different execute process
Rscript $RFILE $ARGUMENTS
#eval "$RUN"
#`Rscript $RFILE $ARGUMENTS`
#$RUN

我验证了我的命令行(通过echo),如果我复制粘贴到我的shell,我可以运行我的R脚本。但是从我的bash,我无法执行我的脚本(但命令行很好)。

使用:Rscript $ RFILE $ ARGUMENTS,Rscript $RFILE $ARGUMENTS和$ RUN,我有这个错误:

Error in parse(text = args[[i]]) : 
  unexpected end of input in ""path_in='/Users/GR/web-app/Rproject/Inputs/Rscript/Gene-level"
Calls: eval -> parse
Execution halted

使用:eval“$ RUN”,我有这个错误:

/Users/GR/web-app/Rproject/Scripts/Rscript.sh: line 38: /Users/GR/web-app/Rproject/Scripts/arg_file_test.R: Permission denied
/Users/GR/web-app/Rproject/Scripts/Rscript.sh: line 44: path_in<-"/Users/GR/web-app/Rproject/Inputs/Rscript/Gene-level Description for Modules.csv": No such file or directory

如果我在我的shell脚本中尝试这个,一切正常:

SCRIPT="/Users/GR/web-app/Rproject/Scripts/arg_file_test.R"
FILE1="path_in='/Users/GR/web-app/Rproject/Inputs/Rscript/Gene-level Description for Modules.csv'"
FILE2="path_in2='/Users/GR/web-app/Rproject/Inputs/Rscript/Template_Auto.csv'"
FILES="\"$FILE1\" \"$FILE2\""
ARG="l=32 w=33"
RUN="Rscript $SCRIPT $FILES $ARG"

有人有想法吗?

由于

6 个答案:

答案 0 :(得分:2)

为什么在bash时这是一个Rscript脚本?那么为什么不把它重写为由Rscript.exe执行的R脚本,允许你测试组件

  • intialization
  • 数据库连接
  • 核心工作
  • ...

单独?

编辑(响应您的评论): R可以通过library()或直接通过source()来调用R,包。你有一个comples的调试问题,你应该尝试删除一些完整性。此外,R脚本可以使用getopt或optparse包来处理命令行参数。

编辑2:您是否知道R有一个RMySQL包允许您从R调用db?

答案 1 :(得分:1)

在Rscript的示例输出中,您引用了:

Error in parse(text = args[[i]]) : 
  unexpected end of input in ""path_in='/Users/GR/web-app/Rproject/Inputs/Rscript/Gene-level"

我注意到那里有非常奇怪的引用:一开始有两个"'后有一个=,只有"个结束。

至少我希望在路径的末尾匹配',并且可能需要平衡那些"以及

我猜它与这一行有关:

RFILE="${RFILE//$SUBSTRING}"

我猜你正在删除该替换中的'之一。

更新:正如其他人指出的那样,您的文件名包含空格。当包含文件名时,始终"放在变量名称的名称周围,尤其是当您知道这些文件名包含空格时。尝试:

Rscript "$RFILE" $ARGUMENTS

答案 2 :(得分:1)

看来你在某处丢失了一些空格。您有此错误消息:

Error in parse(text = args[[i]]) : 
  unexpected end of input in ""path_in='/Users/GR/web-app/Rproject/Inputs/Rscript/Gene-level"

但是从其他文本中,文件名显然应该是

/Users/GR/web-app/Rproject/Inputs/Rscript/Gene-level Description for Modules.csv

这也可以作为您问题的解释,因为您正在进行的变量替换很可能导致包含空格的参数失去其保护性引用。您是否可以将该文件(以及任何其他类似文件)重命名为不包含空格的名称,例如,通过用下划线替换空格,然后重试?

答案 3 :(得分:0)

首先,你可能想尝试在你的mysql行中添加-s(更新-e到-se):

RFILE=$(mysql -u$USER -p$PASS -se "SELECT script_name FROM JobProcess WHERE script_run_id=$ID;" $DB)

您应该可以删除SUBSTRING替代品。 您的变量ARGUMENTS也是如此。在mysql行中用-se替换-e并删除SUBSTRING替换。

这可能无法解决您的问题,但它会删除有关您的扩展替换的任何问题。虽然如果由于某种原因在第一行的末尾有一个\ n或者什么东西,你在$ RFILE和$ ARGUMENTS中替换SUBSTRING ......

答案 4 :(得分:0)

我提供了一份脚本修复程序,但我仍然有一些问题:

#!/usr/bin/env bash
# Execute R process
# -----------------
### Mysql Setup ###
USER=...
PASS=...
HOST=...
DB=...

# Get Job ID process
# Use to retrieve args in my DB
ID=$1

# Get script name
RFILE=$(mysql -u$USER -p$PASS -se "SELECT script_name FROM JobProcess WHERE script_run_id=$ID;" $DB)

# Get script_args
ARGUMENTS=$(mysql -u$USER -p$PASS -se "SELECT script_args FROM JobProcess WHERE script_run_id=$ID;" $DB)

RUN="Rscript $RFILE $ARGUMENTS"
eval "$RUN"

实际上,我不能使用(可能是因为分隔的标记错误):Rscript $ RFILE $ ARGUMENTS,或$ RUN。

此脚本的目的是通过恢复数据库中的所有参数来运行任何R脚本。这是我的数据库中的数据副本:

script_run_id : 161
script_name : /Users/GR/web-app/Rproject/Scripts/arg_file_test.R
script_args : 'path_in<-"/Users/GR/web-app/Rproject/Inputs/Rscript/Gene.csv"' 'path_in2<-"/Users/GR/web-app/Rproject/Inputs/Rscript/Template_Auto.csv"' l=0 w=0 

part script_name定义要调用的R脚本,scripts_args定义与此R脚本一起使用的参数。在此示例中,我的脚本生成以下命令行:

Rscript /Users/GR/web-app/Rproject/Scripts/arg_file_test.R 'path_in<-"/Users/GR/web-app/Rproject/Inputs/Rscript/Gene.csv"' 'path_in2<-"/Users/GR/web-app/Rproject/Inputs/Rscript/Template_Auto.csv"' l=0 w=0

还有更好的方法吗?
例如,为文件路径定义一个新列(例如:script_Files)?
使用逗号分隔参数(例如:l = 0,w = 3,r = 6等),并将字符串拆分为数组(一个例子可以帮助我)?

感谢
ps:一个好方法,可能是直接使用Rscript。

答案 5 :(得分:0)

好吧,我认为您可能需要更改数据库中存储的内容。

你的script_args字段应该在db中看起来像这样:

path_in = \“/ Users / GR / web-app / Rproject / Inputs / Rscript / Gene.csv \”path_in2 = \“/ Users / GR / web-app / Rproject / Inputs / Rscript / Template_Auto.csv \ “l = 0 w = 0

没有任何其他标点符号或转义符...当您填充变量然后在您的eval或其他方法中展开它时,它会在扩展后显示如下:


Rscript /Users/GR/web-app/Rproject/Scripts/arg_file_test.R path_in="/Users/GR/web-app/Rproject/Inputs/Rscript/Gene.csv" path_in2="/Users/GR/web-app/Rproject/Inputs/Rscript/Template_Auto.csv" l=0 w=0

在这种情况下你也可能不需要eval而且你可以在没有eval的情况下单独运行$ RUN,甚至只需要运行

Rscript $RFILE $ARGUMENTS

单独一行。