0

Here's the problem.
I'm trying as "root" user to execute a command as "myusername" user.

That's why I'm using su - $USERNAME -c <command>
The <command> itself is something like sudo sed -i 's|SEARCH_REGEX|REPLACEMENT|' /etc/cloud/cloud.cfg

But each time I execute my script I got an error which seems to be due to the REPLACEMENT part.
I guess this is something around carriage return or spaces.

Here's the code:

#!/bin/bash $USERNAME="myusername" $USERPWD="p@ssw0rd123" PATTERN='s|preserve_hostname:\sfalse|preserve_hostname: true\nmanage_etc_hosts: false|' su - $USERNAME -c 'sudo -S bash -c "sed -i '$PATTERN' /etc/cloud/cloud.cfg"' <<< $USERPWD 

And here's the error I get:

 true\nmanage_etc_hosts:: -c: line 0: unexpected EOF while looking for matching `"' true\nmanage_etc_hosts:: -c: line 1: syntax error: unexpected end of file 

The ressources that helped me:
https://linuxize.com/post/how-to-use-sed-to-find-and-replace-string-in-files/
https://linuxhint.com/50_sed_command_examples/

What am I doing wrong ?

3
  • 1
    So you have a sed inside a bash inside a sudo inside a su! It couldn't but lead to problems with quoting. The first thing is that $PATTERN is not double-quoted, so it will wreck havoc upon expansion. E.g., the pipe character will indeed create a pipeline. Try to clean it up a bit: You can put the sed program in a file, and if you have su why would you need sudo too? Commented Aug 4, 2020 at 22:33
  • I'm not questioning your skills, but maybe you're not aware that su doesn't give root privileges. Many people think that su means super user but in fact su means switch user (or substitute user). You still need root privileges to edit a file for which you don't have the appropriate rights. In addition for sed it does not cause any problem to use the separator of your choice, as long as it does not break the strings. It can be | or @ or : whatever. Anyway thank you, your comment helped me and I was able to find a solution. I will post it during the day. Commented Aug 5, 2020 at 13:02
  • Glad it helped. I am aware of that, but you can also switch user with sudo with the -u flag. I should have been clearer, sorry! But maybe I'm indeed missing a reason that would require you to use both. Yes, sed separator is arbitrary, but since $PATTERN was not double-quoted, upon expansion the pipe character is unprotected and would spawn a pipeline: sed would never see it. Commented Aug 5, 2020 at 17:32

1 Answer 1

1

Thanks to @Quasimodo I finally managed to solve this issue.

First I enhanced the PATTERN readability by splitting the REGEXP and REPLACEMENT into two distinct variables.
Then basically what I made is to change single-quotes to double-quotes and vice versa.

REGEXP="preserve_hostname:\sfalse" REPLACEMENT="preserve_hostname: true\nmanage_etc_hosts: false" PATTERN="s/$REGEXP/$REPLACEMENT/" su - $USERNAME -c "sudo -S bash -c 'sed -n -i \"$PATTERN\" /etc/cloud/cloud.cfg'" <<< $USERPWD 

Note that I escaped the double-quotes around $PATTERN in the sed command.
And that's it!

1
  • I'm still not convinced you need both sudo and su. Why not sudo -u $USERNAME ... instead? It would help. Also, <unix.stackexchange.com/a/95944> shows how to put the sed script in a file, so that you can get rid of one more level of quotes. You may want to try those changes for better readability and reliability. But nice to see you've come to a solution yourself! Commented Aug 5, 2020 at 17:36

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.