1. 问题
    2. 如何在运行时从输入参数创建所需的输入文件?
    3. 我如何调用脚本而不是简单的命令行?
    4. 除了输入绑定之外,我还可以如何向工具传递参数呢?
    5. 目标
    6. 学习如何在运行时动态创建文件。
    7. 学习如何在bash脚本中使用表达式。

    有时,您需要根据输入参数动态创建文件,比如希望从文件而不是命令行参数读取输入配置的工具,或者需要一个小型包装器shell脚本。
    要生成这样的文件,我们可以使用InitialWorkDirRequirement。
    createfile.cwl

    1. class: CommandLineTool
    2. cwlVersion: v1.0
    3. baseCommand: ["sh", "example.sh"]
    4. requirements:
    5. InitialWorkDirRequirement:
    6. listing:
    7. - entryname: example.sh
    8. entry: |-
    9. PREFIX='Message is:'
    10. MSG="\${PREFIX} $(inputs.message)"
    11. echo \${MSG}
    12. inputs:
    13. message: string
    14. outputs:
    15. example_out:
    16. type: stdout
    17. stdout: output.txt

    任何像$(input .message)这样的表达式都在创建文件之前由CWL引擎展开;这里在输入消息处插入值。
    CWL表达式独立于以后在命令行工具调用期间使用的任何shell变量。这意味着对字符$的任何真正需要都必须用\进行转义,例如上面的”\ ${PREFIX}”在生成的文件中被扩展为${PREFIX},由shell脚本而不是CWL引擎进行计算。
    要测试上述CWL工具,请使用此作业提供输入值消息:
    echo-job.yml

    1. message: Hello world!

    在我们运行它之前,让我们更详细地看看每个步骤。base命令baseCommand: [“sh”, “example.sh”]。将执行命令sh example.sh。这将运行我们在shell中创建的文件。
    InitialWorkDirRequirement需要一个listing。由于listing是一个YAML数组,我们需要在数组的每个元素的第一行使用-,在本例中,我们只有一个元素。entryname:可以有任何值,但必须与baseCommand中指定的值匹配。最后一部分是entry:,后面跟着|-这是YAML的引号语法,这意味着你正在使用一个多行字符串(如果没有它,我们将需要在一行上编写整个脚本)。(有关格式的更多信息,请参阅YAML指南)
    运行cwl-runner

    1. $ cwl-runner createfile.cwl echo-job.yml
    2. [job createfile.cwl] /private/tmp/docker_tmphrqxxcdl$ sh \
    3. example.sh > /private/tmp/docker_tmphrqxxcdl/output.txt
    4. Could not collect memory usage, job ended before monitoring began.
    5. [job createfile.cwl] completed success
    6. {
    7. "example_out": {
    8. "location": "file:///home/example/output.txt",
    9. "basename": "output.txt",
    10. "class": "File",
    11. "checksum": "sha1$9045abe4bd04dd8ccfe50c6ff61820b784b64aa7",
    12. "size": 25,
    13. "path": "/home/example/output.txt"
    14. }
    15. }
    16. Final process status is success
    17. $ cat output.txt
    18. Message is: Hello world!