关于shell:为什么我的bash无法执行R脚本?

Why my bash can't execute R script?

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/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,我遇到此错误:

1
2
3
4
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",我有此错误:

1
2
/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脚本中尝试此操作,则一切正常:

1
2
3
4
5
6
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"

有人有主意吗?

谢谢


当您拥有Rscript时,为什么这是bash脚本?那么为什么不将其重写为Rscript.exe执行的R脚本,从而允许您测试组件

  • 初始化
  • 数据库连接
  • 核心工作
  • ...

个别吗?

编辑(根据您的评论):R可以通过library()或直接通过source()调用R。您遇到的调试问题很复杂,应该尝试消除一些复杂性。此外,R脚本可以使用getopt或optparse包来处理命令行参数。

编辑2:您是否知道R有一个RMySQL软件包,该软件包将允许您从R调用数据库?


看来您正在丢失某些地方的空格引用。您有此错误信息:

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

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

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

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


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

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

我注意到那里有一个很奇怪的引号:开头是两个",在=之后是单个',而在结尾仅是一个"

至少我希望在路径的末尾有一个匹配的',并且可能也可以平衡那些"

我猜这与这条线有关:

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

我猜想您要删除该替换中的'之一。

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

1
Rscript"$RFILE" $ARGUMENTS


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

您的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

没有任何其他标点符号或转义符...当您填充变量,然后在评估或其他方法中对其进行扩展时,扩展后将如下所示:

1
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

同样,在这种情况下,您可能不需要评估,您可以自己运行$ RUN而无需评估,甚至只是

1
Rscript $RFILE $ARGUMENTS

仅靠一条线上。


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/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脚本。这是我数据库中的数据副本:

1
2
3
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

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

1
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

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

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


首先,您可能想尝试在MySQL行中添加-s(将-e更新为-se):

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

您应该能够删除SUBSTRING替代品。
变量ARGUMENTS也是如此。在您的mysql行中将-e替换为-se,然后删除SUBSTRING替换。

这可能无法解决您的问题,但是它将消除有关扩展替换的任何问题。尽管如果由于某种原因在第一行的末尾有一个 n或其他内容,您可以在$ RFILE和$ ARGUMENTS中替换SUBSTRING ...