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

String with backslash at the end #10464

Closed
michel-kraemer opened this Issue Mar 14, 2015 · 11 comments

Comments

Projects
None yet
8 participants
@michel-kraemer
Copy link

michel-kraemer commented Mar 14, 2015

I have a file with the following content:

exec "$JAVACMD" \
    "${JVM_OPTS[@]}" \
    -Djava.util.logging.config.file=${VERTX_JUL_CONFIG:-${VERTX_HOME}/conf/logging.properties} \
    -Dvertx.home=$VERTX_HOME\
    -Dvertx.clusterManagerFactory=org.vertx.java.spi.cluster.impl.hazelcast.HazelcastClusterManagerFactory\
    -classpath "$CLASSPATH" \
    org.vertx.java.platform.impl.cli.Starter "$@"

In my playbook I have the following task:

- name: enable log4j
  sudo: yes
  lineinfile: dest={{ vertx_home }}/bin/vertx
    line="    -Dlog4j.configuration=file:$VERTX_HOME/conf/log4j.properties -Dorg.vertx.logger-delegate-factory-class-name=org.vertx.java.core.logging.impl.Log4jLogDelegateFactory \"
    regexp="-Djava\.util\.logging\.config\.file"

When I execute Ansible it says ERROR: There was an error while parsing the task. I figured the problem is the backslash at the end of the line string. However, I need this backslash because in the final file it escapes the line break.

I tried two backslashes \\ but got the same error.

I tried to insert a space between the backslash and the quotation mark, but then the final shell file is invalid (because the backslash escapes the space character and not the line break).

Is this a bug or am I doing something wrong?

Thanks,
Michel

@jimi-c jimi-c added this to the v2 milestone Jul 5, 2015

@jimi-c

This comment has been minimized.

Copy link
Member

jimi-c commented Jul 23, 2015

Hi @michel-kraemer, I've been looking into this and there is a way to get around the parsing error, which involves using the dictionary syntax for arguments:

  - lineinfile:
      dest: "/tmp/test_10464.txt"
      line: "    -Dlog4j.configuration=file:$VERTX_HOME/conf/log4j.properties -Dorg.vertx.logger-delegate-factory-class-name=org.vertx.java.core.logging.impl.Log4jLogDelegateFactory \\"
      regexp: "-Djava\\.util\\.logging\\.config\\.file"

Note the double \\ there, which is required to prevent the YAML parser from thinking you're escaping the quote.

The original issue arises from our key="value" parser thinking that you're escaping that quote, since we do not ourselves check for a double \ to mean use a literal backslash there. I'll continue working on that, to see if I can get it to parse that without error.

@jimi-c jimi-c modified the milestones: next, v2 Jul 23, 2015

@jimi-c

This comment has been minimized.

Copy link
Member

jimi-c commented Jul 23, 2015

Since this has a workaround and would otherwise be a VERY involved changed to the parser, I'm moving this to post-2.0 release milestone.

@albertux

This comment has been minimized.

Copy link

albertux commented Aug 20, 2015

My workaround solution is using hexadecimal code:
line=" ...../bin/cassandra.in.sh \x5C"
this will add: ( with not spaces or anything )
..../bin/cassandra.in.sh \

@albertux

This comment has been minimized.

Copy link

albertux commented Sep 26, 2015

@michel-kraemer

This comment has been minimized.

Copy link
Author

michel-kraemer commented Oct 4, 2015

Awesome idea, @albertux ! I haven't tried it out yet, but it surely looks promising.

@jimi-c jimi-c removed the P3 label Dec 7, 2015

@seeker89

This comment has been minimized.

Copy link

seeker89 commented Apr 28, 2016

Just as a heads up - since I upgraded from 1.9.4 to 2.0.1, the workaround suggested above #10464 (comment) by @albertux is showing a weird behavior - it seems to be inserting the entire block, including the surrounding quotes (both single and double quotes). Not sure where it might be coming from.

@albertux

This comment has been minimized.

Copy link

albertux commented May 2, 2016

@seeker89 I forgot to mention this was using ansible 1.9.3I will try to find a workaround for other versions

@seeker89

This comment has been minimized.

Copy link

seeker89 commented May 2, 2016

@albertux the dictionary syntax works - I'm currently using that everywhere now.

@jimi-c

This comment has been minimized.

Copy link
Member

jimi-c commented Jun 18, 2016

@seeker89 yes the dictionary syntax is still the suggested workaround for this. I have confirmed that works on devel/stable-2.1.

@simonpie

This comment has been minimized.

Copy link

simonpie commented Aug 22, 2016

@albertux's solution is still works very well (and is still necessary) in ansible 2.1.1.0

@abadger

This comment has been minimized.

Copy link
Member

abadger commented Jan 23, 2017

There's a variety of workarounds for this including the ones posted in comments above and using the extra space at the end but running it through jinja2's trim filter:

  - lineinfile: 'dest=/var/tmp/dest line="{{ \"conti nued\\ \" |trim }}" create=True'

However, the supported way to do this in Ansible-2.x is to use yaml dicts:

  - lineinfile:
      dest: /var/tmp/dest
     # Single quotes in yaml do not need to escape the backslash
      line: 'an other\'
      create: True
  - lineinfile:
      dest: /var/tmp/dest
     # double quotes in yaml do need to escape the backslash
      line: "final ly\\"
      create: True

k=v parsing has cornercases like this that will always make it inferior to yaml dicts when there is a need for escaping or complex quoting.

Since yaml dict format works and there are several workarounds if someone feels they must use k=v I'll close this ticket.

@abadger abadger closed this Jan 23, 2017

@ansibot ansibot added bug and removed bug_report labels Mar 6, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment