了解在 sbatch --wrap 语句中使用反引号替换内部变量

Understanding internal variable substitution with backticks in an sbatch --wrap statement

我正在 CentOS 8.1 集群上工作 运行 SLURM 20.02.4。我试图了解如何在 sbatch --wrap= 命令中取消引用变量。我怀疑我可能已达到此类 --wrap 命令的用处极限。

这行得通:

$ X=2 
$ sbatch --wrap="for((i=0; i<3; i++)); do TMP=\"echo ${X} $i\"; echo ${TMP}; done"

它输出:

$ cat slurm-2105323.out
echo 2 0
echo 2 1
echo 2 2

我得到这个声明,我理解:

  1. 我必须转义内联 ",因为我用 " 包装了我的 --wrap= 命令。 \" 确保 sbatch 不会过早终止我的命令。
  2. 取消引用 Xi 是不同的。我可以接受这一点,因为需要区分 --wrap= 命令的外部变量和内部变量。

现在让我们尝试一些更复杂的东西。让我们尝试使用反引号来执行命令并将其分配给变量。

$ X=2 
$ sbatch --wrap="for((i=0; i<3; i++)); do TMP=`echo \"${X} $i\"`; echo ${TMP}; done"

输出

$ cat slurm-2105326.out
2
2
2

很明显,它成功取消了对 X 的引用,但没有成功取消对 i 的引用。我尝试了转义字符、附加 $ 和大括号的各种组合。我似乎无法取消引用 i.

问题:

  1. 如何在上面的命令中取消引用内部变量 i,它是在 sbatch --wrap= 语句中使用反引号执行的?

您需要转义反引号,就像转义内部变量前的引号和 $ 一样。否则它们将被原始 shell 解释,而不是 sbatch 解释 shell 运行,而原始 shell 将

$ sbatch --wrap="for((i=0; i<3; i++)); do TMP=\`echo \"${X} $i\"\`; echo ${TMP}; done"

顺便说一句,在现代 shell 脚本中,最好使用 $() 而不是反引号。更容易看到,它们嵌套正确(您需要使用额外的转义来嵌套反引号)并且读者不太可能将它们误认为引号。您仍然需要转义它以使其在 sbatch shell.

中成为 运行
$ sbatch --wrap="for((i=0; i<3; i++)); do TMP=$(echo \"${X} $i\"); echo ${TMP}; done"