2

我有一个复杂的 qsub 命令可以远程运行。

PROJECT_NAME_TEXT="TEST PROJECT"
PACK_ORGANIZATION="--source-organization \'MY, ORGANIZATION\'"
CONTACT_NAME="--contact-name \'Tom Riddle\'"
PROJECT_NAME_PACK="--project-name \"${PROJECT_NAME_TEXT}\""


INPUTARGS="${PACK_ORGANIZATION} ${CONTACT_NAME} ${PROJECT_NAME_PACK}"

ssh mycluster "qsub -v argv="$INPUTARGS" -l walltime=10:00:00 -l vmem=8GB -l nodes=1:ppn=4 /myscript_path/run.script" 

问题是远程集群无法识别 qsub 命令,它总是显示不正确的 qsub 命令,或者因为输入参数错误而总是在集群上排队。

一定是转义问题,我的问题是如何正确转义上面的命令?

4

4 回答 4

2

尝试使用here-doc执行此操作:您有引号冲突(嵌套双引号是错误的):

#!/bin/bash

PROJECT_NAME_TEXT="TEST PROJECT"
PACK_ORGANIZATION="--source-organization \'MY, ORGANIZATION\'"
CONTACT_NAME="--contact-name \'Tom Riddle\'"
PROJECT_NAME_PACK="--project-name \"${PROJECT_NAME_TEXT}\""


INPUTARGS="${PACK_ORGANIZATION} ${CONTACT_NAME} ${PROJECT_NAME_PACK}"

ssh mycluster <<EOF
qsub -v argv="$INPUTARGS" -l walltime=10:00:00 -l vmem=8GB -l nodes=1:ppn=4 /myscript_path/run.script
EOF

如您所见,here-docs对于带引号的输入非常有帮助。

man bash | less +/'Here Documents'

编辑

从您的评论中:


我使用了这种方法,但它给了我“不会分配伪终端,因为标准输入不是终端。”

您可以忽略此警告

ssh mycluster <<EOF 2>/dev/null

(如果需要,请尝试-t开关)ssh


如果你有

-bash: line 2: EOF: command not found

我认为您有复制粘贴问题。尝试删除所有结束行上的多余空格


而且似乎这种方法无法将本地变量传递$INPUTARGS给远程集群

这似乎与您的EOF问题有关。


$argv在远程集群上不返回任何内容

这是什么意思?$argv不是 中的预定义变量bash。如果您需要列出命令行参数,请使用预定义变量$@


最后一件事:确保您正在使用bash

于 2013-04-02T23:10:04.550 回答
1

您的问题不在于长度,而在于引号的嵌套-在这一行中,您尝试使用"inside ",但这是行不通的:

ssh mycluster "qsub -v argv="$INPUTARGS" -l walltime=10:00:00 -l vmem=8GB -l nodes=1:ppn=4 /myscript_path/run.script"

Bash 将看到它"qsub -v argv="后面是$INPUTARGS(未引用),然后是" -l walltime=10:00:00 -l vmem=8GB -l nodes=1:ppn=4 /myscript_path/run.script".

反斜杠转义这些内部引号可能会产生预期的效果,但是在 bash 中嵌套引号会变得相当混乱。我经常尝试做的是echo在命令的开头添加一个,以显示扩展的各个阶段是如何展开的。例如

echo 'As expanded locally:'
echo ssh mycluster "qsub -v argv=\"$INPUTARGS\" -l walltime=10:00:00 -l vmem=8GB -l nodes=1:ppn=4 /myscript_path/run.script"
echo 'As expanded remotely:'
ssh mycluster "echo qsub -v argv=\"$INPUTARGS\" -l walltime=10:00:00 -l vmem=8GB -l nodes=1:ppn=4 /myscript_path/run.script"
于 2013-04-02T23:10:17.130 回答
0

感谢所有答案,但是他们的方法不适用于我的情况。我必须自己回答这个问题,因为这个问题非常复杂,我从 stackoverflow 中的现有解决方案中得到了线索。

就我而言,有两个问题必须解决。

  1. 将本地程序的参数传递给远程集群。Here-doc 解决方案在这种情况下不起作用。

  2. 使用 long 变量作为包含引号符号的参数在远程集群上运行 qsub。

问题1。

首先,我必须介绍我在本地机器上运行的脚本采用如下参数:

scripttoberunoncluster.py --source-organisation "My_organization_my_department" --project-name "MyProjectName"  --processes 4 /targetoutputfolder/

真正的参数远比上面的长,所以所有的参数都必须发送到remote。它们以这样的文件形式发送:

PROJECT_NAME="MyProjectName"
PACK_ORGANIZATION="--source-organization '\\\"My_organization_my_department\\\"'" # multiple layers of escaping, remove all the spaces
PROJECT_NAME_PACK="--project-name '\\\"${PROJECT_NAME}\\\"'"
PROCESSES_="--processes 4"
TARGET_FOLDER_PACK="/targetoutputfolder/"

INPUTARGS="${PACK_ORGANIZATION} ${PROJECT_NAME_PACK} ${PROCESSES} ${TARGET_FOLDER_PACK}"

echo $INPUTARGS > "TempPath/temp.par"
scp "TempPath/temp.par" "remotecluster:/remotepath/"

我的解决方案有点妥协。但是通过这种方式,远程集群可以运行参数包含引号的脚本。如果您没有将所有变量(作为参数)放在一个文件中并将其传输到远程集群,那么无论您如何将它们传递给变量,引号符号都将被删除。

问题 2。

检查 qsub 如何在远程集群上运行。

ssh remotecluster "qsub -v argv=\"`cat /remotepath/temp.par`\" -l walltime=10:00:00 /remotepath/my.script"

在 my.script 中:

INPUT_ARGS=`echo $argv`

python "/pythonprogramlocation/scripttoberunoncluster.py" $INPUT_ARGS ; #note: $INPUT_ARGS hasn't quote
于 2013-04-04T00:43:19.983 回答
0

所描述的转义问题在于要求在两次评估过程之后保留参数周围的最终引号,即在两次评估之后,我们应该看到如下内容:

--source-organization "My_organization_my_department" --project-name "MyProjectName" --processes 4 /targetoutputfolder/

这可以通过首先将每个参数放在一个单独的变量中,然后用单引号将参数括起来,同时确保参数字符串中可能的单引号被“转义” '\''(实际上,参数将被拆分为单独的字符串,但在使用时,split-up 参数将自动由 UNIX(POSIX?)shell 的字符串评估机制重新连接。而且这个过程必须重复三遍

{
escsquote="'\''"

PROJECT_NAME="MyProjectName"

myorg="My_organization_my_department"
myorg="'${myorg//\'/${escsquote}}'" # bash
myorg="'${myorg//\'/${escsquote}}'"
myorg="'${myorg//\'/${escsquote}}'"
PACK_ORGANIZATION="--source-organization ${myorg}"

pnp="${PROJECT_NAME}"
pnp="'${pnp//\'/${escsquote}}'"
pnp="'${pnp//\'/${escsquote}}'"
pnp="'${pnp//\'/${escsquote}}'"
PROJECT_NAME_PACK="--project-name ${pnp}"

PROCESSES="--processes 4"
TARGET_FOLDER_PACK="/targetoutputfolder/"

INPUTARGS="${PACK_ORGANIZATION} ${PROJECT_NAME_PACK} ${PROCESSES} ${TARGET_FOLDER_PACK}"

echo "$INPUTARGS"
eval echo "$INPUTARGS" 
eval eval echo "$INPUTARGS"
echo
ssh -T localhost <<EOF
echo qsub -v argv="$INPUTARGS" -l walltime=10:00:00 -l vmem=8GB -l nodes=1:ppn=4 /myscript_path/run.script
EOF

}

如需更多信息,请参阅:

于 2014-02-17T09:52:25.227 回答