0

I have an Ansible playbook which is supposed to replace some characters using stream editor.

sed -i "s+foo+$(<replace_file)+g" some_file

or

sed -i "s/foo/$(<replace_file)/g" some_file

cat some_file

line one: foo

cat replace_file

bar

expected result

line one: bar

actual result

line one: $(<bar)

I have tried the command directly on Ubuntu distro and it works perfectly, but running the command through Ansible gives the error.

tripleee
  • 175,061
  • 34
  • 275
  • 318
Sir Blaze
  • 61
  • 2
  • 9
  • 2
    Neither of those first two `sed` commands will work when run directly from the command line; the single quotes inhibit shell expansion so that `$( – larsks Nov 01 '22 at 23:41
  • This is true @larsks, my bad. I was meaning to use `'` instead of `"`. I have gone ahead to edit the post. Do you have a suggestion on hw I can achieve my goal? – Sir Blaze Nov 02 '22 at 06:27

2 Answers2

2

The redirection syntax you are trying to use is a Bash feature; if you are running the script using sh, it will not work (though I would expect a syntax error rather than what you say in your question that you are getting; it is probably no longer correct after you changed the quotes). See also Difference between sh and bash.

Your approach seems extremely brittle, but

sed -i "s+foo+$(cat replace_file)+g" some_file

should work portably in any POSIX shell.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • I understand that ansible uses ```sh``` instead of ```bash``` so I added ``` args: executable: /bin/bash ``` to instruct ansible to use bash as mentioned in the documentation but that gives me the actual output. Using ansible's builtin ```sh``` I get a blank character instead of the mentioned output – Sir Blaze Nov 02 '22 at 18:00
  • I'm not familiar with Ansible but some quick Duck Duck Going suggests that it uses dollar signs for its own variables, so to get a dollar sign passed through to the shell, you need additional shenanigans. Try `\$(` instead of `$(` I guess. The resources I could find say that this depends on which precise context you are in. – tripleee Nov 02 '22 at 18:35
1

Another solution would be to actually use bash as the executable:

- shell: sed -i "s+foo+$(<replace_file)+g" some_file
  args:
    executable: /bin/bash
Kevin C
  • 4,851
  • 8
  • 30
  • 64
  • Hello Kelvin, I used the bash executable in my ansible file but I am getting the output I mentioned. I do not know why this does not work as it is mentioned in the documentation – Sir Blaze Nov 02 '22 at 18:03