使用Slurm+Singularity执行R代码时遭遇语法错误求助
问题:Slurm+srun+Singularity执行R脚本的语法错误
问题场景
我尝试通过Slurm的srun命令,在Singularity容器中执行一段简单的R脚本,脚本内容如下:
project_dir=$HOME/project_directory/ img=$HOME/custom_R_image.img srun \ --job-name=job_03 \ --output="$project_dir/logs/job_03.out" \ --ntasks=1 \ --time=01:00:00 \ --cpus-per-task=2 \ --mem=8G \ --error="$project_dir/logs/job_03.err" \ --mail-type=END \ --mail-user=user.email@example.com \ bash -c ' module load singularity singularity exec --bind '"$HOME"' '"$img"' Rscript -e "print('$HOME/project_directory/')"' '
执行错误
执行后返回如下错误:
Error: unexpected '/' in "print(/" Execution halted
期望效果
期望实现类似如下的执行逻辑:
singularity exec --bind '"$HOME"' '"$img"' Rscript -e "print($root_dir)"'
得到结果:
[1] "/home/project_directory/"
问题原因与解决方案
问题根源
错误出在bash单引号与R字符串的引号嵌套冲突:在bash -c '...'的单引号环境中,你用了'$HOME/project_directory/',这里的单引号会提前闭合bash的单引号上下文,导致R收到的命令变成print(/home/project_directory/)——路径没有被引号包裹,R将/识别为语法错误。
修复方法1:转义R字符串的单引号
在bash单引号环境中,用'\''来插入单引号(逻辑为:'闭合当前bash单引号 → \'输出一个单引号 → '重新打开bash单引号),同时直接复用已定义的$project_dir变量更简洁:
project_dir=$HOME/project_directory/ img=$HOME/custom_R_image.img srun \ --job-name=job_03 \ --output="$project_dir/logs/job_03.out" \ --ntasks=1 \ --time=01:00:00 \ --cpus-per-task=2 \ --mem=8G \ --error="$project_dir/logs/job_03.err" \ --mail-type=END \ --mail-user=user.email@example.com \ bash -c ' module load singularity singularity exec --bind '"$HOME"' '"$img"' Rscript -e "print('\''$project_dir'\'')" '
修复方法2:改用双引号包裹bash -c内容
如果改用双引号包裹bash命令串,内部的双引号需要转义,bash会提前解析变量:
project_dir=$HOME/project_directory/ img=$HOME/custom_R_image.img srun \ --job-name=job_03 \ --output="$project_dir/logs/job_03.out" \ --ntasks=1 \ --time=01:00:00 \ --cpus-per-task=2 \ --mem=8G \ --error="$project_dir/logs/job_03.err" \ --mail-type=END \ --mail-user=user.email@example.com \ bash -c " module load singularity singularity exec --bind $HOME $img Rscript -e \"print('$project_dir')\" "
内容的提问来源于stack exchange,提问作者Victor Cat
相关产品推荐
相关产品推荐

