如何使用CWL将stdout和stderr追加写入指定目录的文件?
报错原因
你遇到的报错是两个原因共同导致的:
- CWL执行任务时会创建独立的临时工作目录,你通过
stdout字段指定的输出文件默认会直接生成在工作目录根路径下,不会自动创建你指定的out_directory目录,也不会把文件写入该目录,因此匹配out_directory/out_file路径时找不到文件。 >>追加写入是shell专属语法,CWL默认直接执行命令不启动shell,这类重定向语法不会生效,你原本的写法也实现不了追加写入的效果。
解决方法
要同时实现指定目录输出、合并stdout/stderr、追加写入三个需求,需要开启shell支持,用shell命令包裹你的执行逻辑,示例如下:
修改后的test.cwl
# File: test.cwl cwlVersion: v1.0 class: CommandLineTool requirements: - class: InlineJavascriptRequirement # 开启Shell支持,才能使用重定向、追加等shell语法 - class: ShellCommandRequirement baseCommand: [sh, -c] inputs: message: type: string output_name: type: string output_dir: type: string arguments: # 直接编写完整shell逻辑:先创建输出目录,再执行追加写入、合并stderr - valueFrom: > mkdir -p $(inputs.output_dir) && printf '$(inputs.message)' >> $(inputs.output_dir)/$(inputs.output_name) 2>&1 shellQuote: false outputs: output: type: File outputBinding: glob: $(inputs.output_dir)/$(inputs.output_name)
输入文件test.yml无需修改,直接运行即可。
补充说明
如果需要多次执行该CWL任务时始终追加到同一个历史文件,需要将输出目录作为Directory类型的输入挂载到任务的工作目录中,因为CWL默认每次任务都在全新的临时工作目录执行,不挂载的情况下历史文件不存在,>>会默认创建新文件,效果和覆盖写入一致。
内容的提问来源于stack exchange,提问作者nefeli0
相关产品推荐
相关产品推荐

