Escaping shell character in groovy jenkins pipeline - shell

I have some issue to escape quote character in my jenkins pipeline. for example :
I want to append a text in to file through the pipeline using this command below:
openshift.rsh("${podname}", """sh -c 'echo "define( 'WP_HOME', 'http://rabah-test.com' );" >> wp-config.php'""")
and expecting this in to the wp-config.php file:
define( 'WP_HOME', 'http://rabah-test.com' );
but unfortunately i don't have the quotes in my result :
define( WP_HOME, http://rabah-test.com );

I believe it is not an issue with jenkins. Try to run your command in the terminal first.
You have a simple quotes for your sh command and simple quotes inside the define.
I would try something like
sh -c 'echo "define( \'WP_HOME\', \'http://rabah-test.com\' );" >> wp-config.php'
Note, instead of adding the define to the wp-config.php file, I would be tempted to version a default WP_HOME and replace it by a sed

I found how to deal with it. Instead of using simple quotes, I decided to use double quotes and escape with two backslashes.
Like this:
sh -c 'echo "define( \\" WP_HOME \\" , \\" http://rabah-test.com \\" );" >> wp-config.php'
And it now works perfectly.

Related

Search sub string then Replace Line in a file without regex

I want to run a script to search the /etc/bash.bashrc file for the substring
PS1=
and replace the entire line with:
PS1='\[\e[36m\]\h\[\e[m\]\[\e[33m\]#\[\e[m\]\[\e[33m\]\u\[\e[m\]:\[\e[32m\]\W\[\e[m\]>\\$ '
This new line is intended to change the cli prompt.
I have tried and tried sed in a bash script but I couldn't get the regex right.
[Edit] This code now works:
#!/bin/bash
custom_prompt='${debian_chroot:+($debian_chroot)}\[\e[36;40m\]\u\[\e[m\]\[\e[93m\]#\[\e[m\]\[\e[36m\]\h\[\e[m\]:\[\e[92m\]\w\[\e[m\]\[\e[92m\]\\$\[\e[m\]\[\e[93m\]>\[\e[m\]\'
### Setup Bash Prompt
# replace each \ for double \\ in the prompt string
sed_custom_prompt=$(<<<"$custom_prompt" sed 's/\\/\\\\/g')
# add this to /etc/bashrc for global effect
sed -i "s/PS1=.*/PS1=\"$sed_custom_prompt\"/" testrc
The only problem is that it does PS1= " string "
rather than PS1 = ' string ' with back tics.
I need a simple old fashioned non-regex script that finds a string and replaces a line in a file. Regex can find the string but my original statement messed up the substitution.
I don't care if it is perl, awk or bash. I just need something that works.
Instead of writing scripts to replace the existing PS1 jest overwrite it it's much simpler.
echo PS1="This is my prompt" >> /etc/bash.bashrc
This wil append the new PS1 to the end of the file and since this in the end it will overwrite the default PS1 initialization.
You should escape every \ to make sure they aren't lost.
EDIT: The PS1 string should be wrapped with double quotes as well.
$ custom_prompt="\[\e[36m\]\h\[\e[m\]\[\e[33m\]#\[\e[m\]\[\e[33m\]\u\[\e[m\]:\[\e[32m\]\W\[\e[m\]>\\$ "
$ sed_custom_prompt=$(<<<"$custom_prompt" sed 's/\\/\\\\/g')
$ sed -i "s/PS1=.*/PS1=\"$sed_custom_prompt\"/" testrc
$ source testrc
laptop#user:~>$
The following code works on my laptop. The problem was in last \ character in the string of your PS1 variable (I removed it):
#! /bin/bash
custom_prompt='${debian_chroot:+($debian_chroot)}\[\e[36;40m\]\u\[\e[m\]\[\e[93m\]#\[\e[m\]\[\e[36m\]\h\[\e[m\]:\[\e[92m\]\w\[\e[m\]\[\e[92m\]\\$\[\e[m\]\[\e[93m\]>\[\e[m\] '
### Setup Bash Prompt
# replace each \ for double \\ in the prompt string
sed_custom_prompt=$(<<<"$custom_prompt" sed 's/\\/\\\\/g')
# add this to /etc/bashrc for global effect
sed -i "s/PS1=.*/PS1='$sed_custom_prompt'/" testrc
exit 0
p.s. I personally like to add the time to the PS1 so I know how long ago a command is exited. Also, you can immediately time stuff if you add it (\D{%H}:\D{%M}).
Try this:
replace='PS1="\[\e[36m\]\h\[\e[m\]\[\e[33m\]#\[\e[m\]\[\e[33m\]\u\[\e[m\]:\[\e[32m\]\W\[\e[m\]>\\$ "'
perl -i -spe 's/^PS1=.*$/$repl/' -- -repl="$replace" -- /etc/bash.bashrc
Note: Maybe remove the -i (in-place edit) in the first run to check if it works.

sed - How to ignore many special characters together in a string

I have many shell commands in a large shell script. I want to comment many of them. For eg
exec_cmd "mkdir -p $dockerHome/devicemapper/devicemapper"
I am able to replace this command with :
sed -i -e "s/exec_cmd \"mkdir \-p \$dockerHome\/devicemapper\/devicemapper\"/\#exec_cmd \"mkdir \-p \$dockerHome\/devicemapper\/devicemapper\"/g" check
Now, there are quite a few commands like this in a file. Is there a way to write a sed command which ignores all the special characters at once since otherwise the alternative seems to be putting a backslash in front of all special characters in the strings to be replaced.
Perl to the rescue.
Its quotemeta function quotes all the metacharacters for you.
#! /usr/bin/perl -pl
use warnings;
BEGIN {
$regex = join '|', map quotemeta, split /\n/, << '__LIST__';
exec_cmd "mkdir -p $dockerHome/devicemapper/devicemapper"
another command to be commented
__LIST__
$regex = qr/^($regex)$/;
}
s/$regex/$1 ? "# $1" : $_/e
Just fill in the script lines to comment before the __LIST__. Save to a file, run as
perl script.pl input-file > output-file
To edit the input file directly, you can use the -i option.

Escaping $ variable in sed over ssh command?

I have a command like this:
ssh user#hostname 'sed -e "s|foo|${bar}|" /home/data/base_out.sql > /home/data/out.sql'
The sed command is working in local shell. But it is not expanding the variable over ssh command. Thanks!
The rule is that within single quotes, parameters are not expanded. You have single quotes around the entire command.
Try this:
ssh user#hostname "sed -e 's|foo|$bar|' /home/data/base_out.sql > /home/data/out.sql"
Now $bar is expanded before the command string is passed as an argument to ssh, which is what you want.
I removed the curly braces around ${bar} because I believe they offer a false sense of security. In this case, they are not protecting you against any of the issues associated using shell variables in sed commands.

echo a one-liner bash script with variables

I would like to do that:
i="1"; echo -e '#!/usr/bin/env bash\nmyprogram -i "input_${i}.txt"'
and pipe it to a job scheduler.
However, this doesn't replace the variable i by its value. Instead, I obtain this:
#!/usr/bin/env bash
myprogram -i "input_${i}.txt"
I played a bit with option -e of echo and with single-/double-quote but could not make it work. For instance, I get this:
i="1"; echo -e "#!/usr/bin/env bash\nmyprogram -i \"input_${i}.txt\""
-bash: !/usr/bin/env: event not found
My bash version is 4.1.2.
Try this:
i="1"; echo -e '#!/usr/bin/env bash\nmyprogram -i '"\"input_${i}.txt\""
You can echo single- and double-quoted strings at the same time.
Try also escaping the exclamation mark:
\! should be okay, and will not be read as an "event" by bash.
i="1"; echo -e '#!/usr/bin/env bash\nmyprogram -i "input_'"${i}"'.txt"'
Basically, use single quotes until you need to interpolate, then close the single quotes, open the double quotes, add the interpolation, close the double quotes, reopen single quotes, and finish the string. In the shell, quotation marks don't delimit a word; they just change the interpretation of the part of a word falling between them.

Bash sed implementation replace with semi-colon

I'm trying to automate an install script for New Relic and in my bash file I have the following:
_APPNAME="Test Application"
_OLD=";newrelic.appname = \"PHP Application\""
_NEW="newrelic.appname = \"${_APPNAME}\""
sed -i 's/$_OLD/$_NEW/g' /etc/php.d/newrelic.ini
For some reason that sed command doesn't trigger at all, can anyone see anything wrong with this logic?
Note I have also tried ${_OLD} and ${_NEW} to no avail.
$_OLD and $_NEW are not expanded inside single quotes. '
Use double quotes " instead:
sed -i "s/$_OLD/$_NEW/g" /etc/php.d/newrelic.ini

Resources