<p>In order to reference a WDL input within a command block you need to use an <a href="https://github.com/openwdl/wdl/blob/main/versions/1.1/SPEC.md#expression-placeholders-and-string-interpolation" rel="nofollow noreferrer">expression placeholder</a>. Expression placeholders have the form <code>~{*wdl expression*}</code>, where the inner part can be an valid WDL expression (ie reference to an input declaration)</p>
<p>When an engine sees a <code>String</code> or a <code>command</code> block, it first looks to see if there are any of these expression placeholders within it. If there are, it will evaluate the inner expression, and replace the entire placeholder <code>~{...}</code> with the resulting value.</p>
<p>You can see how this can be applied below</p>
<pre><code>String first_name = &quot;John&quot;
String last_name = &quot;Smith&quot;
Int age = 45


String full_name = &quot;~{first_name} ~{last_name} # equals &quot;John Smith&quot;
String name_and_age = &quot;John is ~{age}&quot; # equals &quot;John is 45

# Any valid WDL expression can go within an expression placeholder
String complex = &quot;~{first_name + last_name + age}&quot; # equals &quot;JohnSmith45&quot;
</code></pre>
<p>A key thing to note is that WDL command templating and expression evaluation is completely separate from the actual execution of the command. An execution engine will evaluate the command template, swap the expression placeholders with their evaluated values, and  <em>THEN</em>, execute the script.</p>
<p>This is relevant for your use case since you are using heredoc to directly define the rscript you are runnning. If we briefly look at a python example, you can see what I mean:</p>
<pre><code>task hello_world {
  input {
   String name = &quot;john&quot;
  }

  command &lt;&lt;&lt;
   python &lt;&lt;CODE
     # this is valid, because once the placeholder evaluates
     # this command becomes name = &quot;john&quot;, which is valid python syntax
     # We did not have to pass ~{name} as an arg to the python command
     name = &quot;~{name}&quot;
     print(name)
   CODE
  &gt;&gt;&gt;
}
</code></pre>
<hr />
<p>Now getting to your problem specifically. You are trying to reference the <code>name</code> input value without using any sort of expression placeholder. To the execution engine, the <code>name</code> value looks like any other string. To swap the <code>name</code> in the command for the value passed into the task, you simply need to wrap the variable name in an expression placeholder: <code>~{name}</code>.</p>
<pre><code>task PrintNameR {
  input {
    String name
  }

  command&lt;&lt;&lt;
    # I would wrap this in quotes to prevent any side effects of 
    # shell expansion
    R --no-save --args '~{name}' &lt;&lt;Rscript
    args &lt;- commandArgs(trailingOnly = TRUE)
    for (i in args){
    print(i)}
    Rscript
  &gt;&gt;&gt;

  runtime {
            docker: &quot;firsttrydocker&quot;
  }
  
  output {
     File output_R = stdout()
  }
}
<span class="math-container">```</span>
</code></pre>

CC BY-SA 4.0
2022-05-17T02:01:34.363Z
2022-05-17T02:01:34.363Z
Patrick Magee
<p>I figured I had to pass ~{sep=&quot; &quot; name} as an argument</p>
<pre><code>command&lt;&lt;&lt;
R --no-save --args ~{sep=&quot; &quot; name} &lt;&lt;Rscript
args &lt;- commandArgs(trailingOnly = TRUE)
for (i in args){
print(i)}
Rscript
</code></pre>
<blockquote>
<blockquote>
<blockquote>
</blockquote>
</blockquote>
</blockquote>

CC BY-SA 4.0
2022-03-14T20:05:20.967Z
2022-03-14T20:05:20.967Z
binn
<p>I am trying to run an R script as a task in WDL in a docker image. Since this is my first time working with these, I am stuck in something very simple (and in the initial stage) and am hoping somebody here can point me in the right direction.
Here is my dockerfile.</p>
<pre><code>FROM rocker/r-base:latest
RUN Rscript ...r-docker/install_packages.R
</code></pre>
<p>Here is my WDL script</p>
<pre><code>version 1.0

workflow Rpipe {
   input {
     String name
   }
  call PrintNameR{
        input:
        name = name
}
  output {
     File outfile = PrintNameR.output_R
  }
}

task PrintNameR {
      input {
           String name
}

command&lt;&lt;&lt;
    R --no-save --args name &lt;&lt;Rscript
    args &lt;- commandArgs(trailingOnly = TRUE)
    for (i in args){
    print(i)}
    Rscript
  &gt;&gt;&gt;

runtime {
            docker: &quot;firsttrydocker&quot;
       }
output {
     File output_R = stdout()
  }
}
</code></pre>
<p>I validated, generated an input json file - edited it to include the string I want &quot;Smith&quot;, and ran it.</p>
<pre><code>java -jar ../cromwell/womtool-77.jar validate rtry1.wdl 
java -jar ..cromwell/womtool-77.jar inputs rtry1.wdl &gt; rtry1.json 
java -jar ..cromwell/cromwell-77.jar run rtry1.wdl --inputs rtry1.json
</code></pre>
<p>I get an output:</p>
<pre><code>&gt; args &lt;- commandArgs(trailingOnly = TRUE)
&gt; for (i in args){
+ print(i)}
[1] &quot;name&quot;
</code></pre>
<p>I get &quot;name&quot;, I wanted to get &quot;Smith&quot; because that's what my input is.</p>
<p>What am I doing wrong? Clearly, it seems that I am not passing the WDL task input to the WDL task command -in the Rscript. What is the proper way to do it?</p>

<r><wdl><docker>
Wrapping R scripts in WDL and run in docker
# Wrapping R scripts in WDL and run in docker

(Asked by: username_0 on 2022-03-14)

I am trying to run an R script as a task in WDL in a docker image. Since this is my first time working with these, I am stuck in something very simple (and in the initial stage) and am hoping somebody here can point me in the right direction.
Here is my dockerfile.
FROM rocker/r-base:latest
RUN Rscript ...r-docker/install_packages.R

Here is my WDL script
version 1.0

workflow Rpipe {
   input {
     String name
   }
  call PrintNameR{
        input:
        name = name
}
  output {
     File outfile = PrintNameR.output_R
  }
}

task PrintNameR {
      input {
           String name
}

command<<<
    R --no-save --args name <>>

runtime {
            docker: "firsttrydocker"
       }
output {
     File output_R = stdout()
  }
}

I validated, generated an input json file - edited it to include the string I want "Smith", and ran it.
java -jar ../cromwell/womtool-77.jar validate rtry1.wdl 
java -jar ..cromwell/womtool-77.jar inputs rtry1.wdl > rtry1.json 
java -jar ..cromwell/cromwell-77.jar run rtry1.wdl --inputs rtry1.json

I get an output:
> args <- commandArgs(trailingOnly = TRUE)
> for (i in args){
+ print(i)}
[1] "name"

I get "name", I wanted to get "Smith" because that's what my input is.
What am I doing wrong? Clearly, it seems that I am not passing the WDL task input to the WDL task command -in the Rscript. What is the proper way to do it?

**Tags:** r, wdl, docker

---

## 2 answers

### Answer by username_1 on 2022-05-17. Score: 2 | Accepted answer

In order to reference a WDL input within a command block you need to use an expression placeholder. Expression placeholders have the form ~{*wdl expression*}, where the inner part can be an valid WDL expression (ie reference to an input declaration)
When an engine sees a String or a command block, it first looks to see if there are any of these expression placeholders within it. If there are, it will evaluate the inner expression, and replace the entire placeholder ~{...} with the resulting value.
You can see how this can be applied below
String first_name = "John"
String last_name = "Smith"
Int age = 45


String full_name = "~{first_name} ~{last_name} # equals "John Smith"
String name_and_age = "John is ~{age}" # equals "John is 45

# Any valid WDL expression can go within an expression placeholder
String complex = "~{first_name + last_name + age}" # equals "JohnSmith45"

A key thing to note is that WDL command templating and expression evaluation is completely separate from the actual execution of the command. An execution engine will evaluate the command template, swap the expression placeholders with their evaluated values, and  THEN, execute the script.
This is relevant for your use case since you are using heredoc to directly define the rscript you are runnning. If we briefly look at a python example, you can see what I mean:
task hello_world {
  input {
   String name = "john"
  }

  command <<<
   python <>>
}


Now getting to your problem specifically. You are trying to reference the name input value without using any sort of expression placeholder. To the execution engine, the name value looks like any other string. To swap the name in the command for the value passed into the task, you simply need to wrap the variable name in an expression placeholder: ~{name}.
task PrintNameR {
  input {
    String name
  }

  command<<<
    # I would wrap this in quotes to prevent any side effects of 
    # shell expansion
    R --no-save --args '~{name}' <>>

  runtime {
            docker: "firsttrydocker"
  }
  
  output {
     File output_R = stdout()
  }
}
```


---

### Answer by username_0 on 2022-03-14. Score: 4

I figured I had to pass ~{sep=" " name} as an argument
command<<<
R --no-save --args ~{sep=" " name} <


---

