这是我提出的问题的延伸。 将目录从命令行传递到 shell 脚本
我有一个脚本,它使用定界符编写另一个脚本。我需要能够在定界文档中写入未展开的变量,因此我使用单引号 ( 'EOF'
)。但是,我需要扩展一个变量。给定下面的脚本,我如何$sourcedir
在heredoc中写入 的值?
#!/bin/bash
sourcedir="$1"
cd $sourcedir
find "$PWD" -maxdepth 2 -name \*_R1*.fastq.gz > list1
fastq_list=$sourcedir/list1 echo `cat $fastq_list` num_files=$(wc -l <
$sourcedir/list1) echo $num_files
cat > run_array_job.sh<<'EOF'
#!/bin/bash -l
#$ -j y
#$ -cwd -S /bin/sh
#$ -l h_vmem=10G
#$ -pe smp 12
if [ -z "${SGE_TASK_ID}" ]; then echo "Need to set SGE_TASK_ID" exit 1 fi
BASEDIR=$sourcedir
echo "BASEDIR" echo $BASEDIR
BASEFILES=$( ls *_R1.fastq.gz)
BASEFILES_ARRAY=(${BASEFILES})
BASEFILE=${BASEFILES_ARRAY[(${SGE_TASK_ID} - 1)]}
echo $BASEFILE
...................
...................
EOF
qsub -t 1-${num_files} run_array_job.sh
我正在使用运行这个脚本
bash script.sh /home/dir/data
我可以将 /home/dir/data 作为 $1 传递到 sourcedir,但它还需要传递到 BASEDIR ,在使用 qsub 提交到集群的数组脚本中。
答案1
您可以最直接地根据您的使用情况来执行此操作,只需将您的heredoc分成两部分:
cat > run_array_job.sh<<'EOF'
#!/bin/bash -l
...
EOF
printf 'BASEDIR="%s"\n" "$sourcedir" >> run_array_job.sh
cat >> run_array_job.sh<<'EOF'
echo "BASEDIR" echo $BASEDIR
...
EOF
qsub -t 1-${num_files} run_array_job.sh
这只是构建文件的第一部分,使用 附加您想要在第一部分末尾可用的变量的单行>>
,然后以相同的方式将文档的其余部分连接到末尾。
最后你会得到相同的连贯文件,并且只需要额外编写几行。如果您有多个变量要传递,您也可以将它们一次性全部放入。
答案2
这有点难以做到,因为与引号不同,您不能在此处文档中停止并重新启动扩展。但我们可以使用以下命令对此处文档进行后处理sed
:
#!/bin/bash
sourcedir=/some/path
sed -e "s,%%sourcedir%%,$sourcedir,g" << 'EOF'
some commands here with $variables not expanded
except for the special %%sourcedir%%, which is
EOF
运行产生输出:
some commands here with $variables not expanded
except for the special /some/path, which is
该sed
命令只是简单地更改 的所有实例,%%sourcedir%%
无论其值如何$sourcedir
(只要它不包含逗号;s
那么您需要将命令的分隔符更改为其他内容。)
为了清楚起见,我将占位符更改为另一种格式,但您也可以将其保留为$sourcedir
然后使用sed -e "s,\$sourcedir,$sourcedir,"
. (尽管请注意,它也会匹配$sourcedirectory
和其他类似的变量,但${sourcedir}
即使这在 shell 中是等效的。)
或者,使用GNUenvsubst
在文档上,如果您有它(它是 的一部分gettext
):
#!/bin/bash
export sourcedir=/some/path
envsubst '$sourcedir' << 'EOF'
some commands here with $variables not expanded
except for the special $sourcedir, which is
EOF