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 /home/docs/checkouts/readthedocs.org/user_builds/common-workflow-languageuser-guide-zh-hans/envs/latest/bin/cwltool 3.1.20240508115724
INFO Resolved 'createfile.cwl' to 'file:///home/docs/checkouts/readthedocs.org/user_builds/common-workflow-languageuser-guide-zh-hans/checkouts/latest/src/_includes/cwl/creating-files-at-runtime/createfile.cwl'
INFO [job createfile.cwl] /tmp/dh8qu9yi$ sh \
    example.sh > /tmp/dh8qu9yi/output.txt
INFO [job createfile.cwl] completed success
{
    "example_out": {
        "location": "file:///home/docs/checkouts/readthedocs.org/user_builds/common-workflow-languageuser-guide-zh-hans/checkouts/latest/src/_includes/cwl/creating-files-at-runtime/output.txt",
        "basename": "output.txt",
        "class": "File",
        "checksum": "sha1$9045abe4bd04dd8ccfe50c6ff61820b784b64aa7",
        "size": 25,
        "path": "/home/docs/checkouts/readthedocs.org/user_builds/common-workflow-languageuser-guide-zh-hans/checkouts/latest/src/_includes/cwl/creating-files-at-runtime/output.txt"
    }
}INFO Final process status is success
$ cat output.txt
Message is: Hello world!