Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When using shell in processes, some backslashes still need to be escaped #67

Closed
mfoll opened this issue Aug 18, 2015 · 2 comments
Closed

Comments

@mfoll
Copy link

mfoll commented Aug 18, 2015

In this sed command, the backslashes need to be escaped when used in shell:

bash-3.2$ echo "Hello lg:en" | sed "s/.*lg:\(.*\).*/\1/"
en

In a nextflow shell process (see below), this would result in:

ERROR ~ startup failed:
test.nf: 11: unexpected char: '\' @ line 11, column 29.
     echo "!{x}" | sed "s/.*lg:\(.*\).*/\1/"

But it works when escaping the three backslashes. However, the \t in printf "This \t works" doesn't need to be escaped:

echo true

cheers = Channel.from 'Bojour lg:fr', 'Ciao lg:it', 'Hello lg:en', 'Hola lg:es', 'Γεια σου lg:gr'

process sayHello {
  input: 
  val x from cheers

  shell:
  '''
  echo "!{x}" | sed "s/.*lg:\\(.*\\).*/\\1/"
  printf "This \t works"
  '''
}
@pditommaso
Copy link
Member

The problem here is that the backslash character is interpreted by the Groovy syntax parser as the string escape character. Thus is no way to fix this.

Note that \n and \t are not managed in a special way, they are simply replaced with the equivalent special character #13 and #09 in the produced shell script.

There are two possible workarounds to handle your use case.

The first, Groovy allows an alternative syntax for string definitions which uses the $ as escape character in place of \ character. These strings are delimited with an opening $/ and and a closing /$. Thus your script should be defined like this:

shell:
$/
echo "Hello lg:en" | sed "s/.*lg:\(.*\).*/\1/" 
/$

However note that $SOMETHING will be parsed as a string variable. You can read more about this string syntax here.

Another option is to include your script into a external template. For example you could have a file

templates/sed.txt:

echo "Hello lg:en" | sed "s/.*lg:\(.*\).*/\1/"

Then use it in the process like this:

process foo {
  shell:
  template('sed.txt')
}

See the doc here.

@mfoll
Copy link
Author

mfoll commented Aug 26, 2015

Thanks for the suggestions. The dollar slashy string is still not a perfect solution (in term of having pure bash code inside), as one has to escape the dollar sign now with a dollar. For example when using a bash variable:

  shell:
  $/
  lang=$(echo "!{x}" | sed "s/.*lg:\(.*\).*/\1/")
  echo "$$lang"
  /$

Anyway, that's clearly a minor point, and having templates is a good workaround.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants