2.14. 在运行时创建文件#
有些情况下,您需要根据输入参数动态创建文件。例如有的工具需要通过文件(而非命令行参数)读取输入配置,还有的需要小型 shell 脚本作为包装器 (wrapper).
To generate such files, we can use the InitialWorkDirRequirement
.
createfile.cwl
##!/usr/bin/env cwl-runner
cwlVersion: v1.2
class: CommandLineTool
baseCommand: ["sh", "example.sh"]
requirements:
InitialWorkDirRequirement:
listing:
- entryname: example.sh
entry: |-
PREFIX='Message is:'
MSG="\${PREFIX} $(inputs.message)"
echo \${MSG}
inputs:
message: string
outputs:
example_out:
type: stdout
stdout: output.txt
在创建文件之前,CWL引擎将扩展所有形如 $(inputs.message)
的表达式。此处将插入输入项message
实际的值。
小技巧
_CWL 表达式 _ 与后期在命令行工具调用时用到的任何 _shell 变量 _ 是相互独立的。这意味着,所有(后期)实际用到字符 $
的地方必须由 \
(斜线)字符加以** 转义 **。例如,上例中的 \${PREFIX}
在生成的文件中扩展为 ${PREFIX}
,以供 shell 脚本(而非 CWL 引擎)计算其值。
测试上述 CWL 工具时,请使用此作业提供输入项 message
的值:
echo-job.yml
#message: Hello world!
运行前,我们来细看一下每个步骤。基础命令 baseCommand: ["sh", "example.sh"]
将执行的命令是 sh example.sh
. 这将在 shell 中运行我们创建的文件。
InitialWorkDirRequirements
需要一个 listing
。由于 listing
是个 YAML 数组,我们需要在数组每个元素的首行添加一个 -
字符,不过本示例中只有一个元素。entryname:
可以取任何值,但它必须与 baseCommand
中指定的值相匹配。最后的部分是 entry:
,后面跟着 |-
,这是 YAML 中表示引用的语法,意味着此处使用的是多行字符串(要是没有它,我们就得将整个脚本写在同一行之内)。
备注
请参阅《YAML 指南》 ,进一步了解代码格式。
现在,在命令行上以工具描述和输入对象为参数调用 cwltool
:
$ cwltool createfile.cwl echo-job.yml
INFO /opt/hostedtoolcache/Python/3.9.19/x64/bin/cwltool 3.1.20240508115724
INFO Resolved 'createfile.cwl' to 'file:///home/runner/work/user_guide/user_guide/src/_includes/cwl/creating-files-at-runtime/createfile.cwl'
INFO [job createfile.cwl] /tmp/fp050u4n$ sh \
example.sh > /tmp/fp050u4n/output.txt
INFO [job createfile.cwl] completed success
{
"example_out": {
"location": "file:///home/runner/work/user_guide/user_guide/src/_includes/cwl/creating-files-at-runtime/output.txt",
"basename": "output.txt",
"class": "File",
"checksum": "sha1$9045abe4bd04dd8ccfe50c6ff61820b784b64aa7",
"size": 25,
"path": "/home/runner/work/user_guide/user_guide/src/_includes/cwl/creating-files-at-runtime/output.txt"
}
}INFO Final process status is success
$ cat output.txt
Message is: Hello world!