How can i modify a remote file over ssh with sed? - linux

i am trying to add a line to the top of a JS file on a remote server
the command i want to run is:
sed -i "1i\const test = require(\'../../../test/test.json\');" /opt/test.js
so i have tried the following:
ssh user#host "sed -i "1i\const test = require(\'../../../test/test.json\');" /opt/test.js"
this gives me an error due to the "(" and ")" so i added a "\" before them:
ssh user#host "sed -i "1i\const test = require\(\'../../../test/test.json\'\);" /opt/test.js"
however i still get the error:
bash: -c: line 0: syntax error near unexpected token `('
how can i fix this?

Rather than use sed -i (which just manages a temp file behind the scenes), use ed and provide the script (via ssh) to ed's standard input.
ssh user#host 'ed /opt/test.js' <<'EOF'
1i
const test = require('../../../test/test.json');
.
wq
EOF

Related

Ubuntu pass Password containing '"' to sudo

I am trying to pass the password that contains " character as part of my password in a bash script to sudo -S su. I am running the bash script but I get prompt as bash error: line1 EOF as end to " not found.
Suggest some method to pass the password containing quotes successfully.
echo "pass\"word" | sudo -S su
prompt:
bash error: line1 EOF as end to '"' not found
I want to run the bash script without errors
This error is not caused by the quote in your password, but by the fact that both sudo and the shell spawned by su are trying to read from stdin:
$ bash -c 'pass"word'
bash: -c: line 1: unexpected EOF while looking for matching `"'
bash: -c: line 2: syntax error: unexpected end of file
$ echo 'totallynotmypassword' | sudo -S su
bash: line 1: totallynotmypassword: command not found
As suggested by user KamilCuk, it is better to create a NOPASSWD entry in your sudoers file.

How to handle quotes, backtick special characters for running linux bash shell command in remote server

Someone, please help me in correcting below command I wasted more than a day fixing below but failed, please help, I will be using below in ansible shell module.
ssh -o ConnectTimeout=5 splunk#10.145.32.172 '
sdline="`
grep -n TA-aws-hf-{{client_code}}-{{env_name}} /opt/splunk/etc/system/local/serverclass.conf
| awk -F \":\" \'{print $1}\'
`
&& sed -ie \"$sdline,`
echo $sdline + 3
| bc
`d\" /opt/splunk/etc/system/local/serverclass.conf
"
> ^C
Even tried below way:
ssh -o ConnectTimeout=5 splunk#10.145.32.172 exec sdline=`grep -n TA-aws-hf-{{client_code}}-{{env_name}} /opt/splunk/etc/system/local/serverclass.conf|awk -F ":" '{print $1}'` && sed -ie "$sdline,`echo $sdline + 3|bc` d" /opt/splunk/etc/system/local/serverclass.conf
grep: /opt/splunk/etc/system/local/serverclass.conf: No such file or directory
bash: line 0: exec: sdline=: not found
Context: It seems this question originated as an XY Problem. OP appears to want to remove the 3 lines including and after the string "TA-aws-hf-{{client_code}}-{{env_name}}".
Backticks are deprecated; use $(modern $(command) substitution) when necessary. It is not necessary in this case.
If your remote server has GNU sed:
ssh splunk#10.145.32.172 'sed -i "/TA-aws-hf-{{client_code}}-{{env_name}}/,+2d" /opt/splunk/etc/system/local/serverclass.conf'
If that gives you sed: -e expression #1, char 19: unexpected ',':
ssh splunk#10.145.32.172 '
cd /opt/splunk/etc/system/local
awk "/TA-aws-hf-{{client_code}}-{{/ {i=-3} i++>0" \
serverclass.conf > temp && mv $_ serverclass.conf
'
Your remote command is quite complicated.
I suggest the following:
Use ssh to gain interactive shell in 10.145.32.172
Create a script on 10.145.32.172 that do the work, with everything hard coded.
Refactor command line parameters to your script.
Call your script remotely from your local machine.
This strategy simplify the script and its maintenance. Allowing you to send only the important parameters.
If you have to deploy the script on many remote machines. Use shared storage resources, like NFS. Optionally copy the script using scp prior to running it.

SED in remote SUDO ssh script

I am trying to disable RHN check when running yum on 1000 servers. It is done by:
Editing this file /etc/yum/pluginconf.d/rhnplugin.conf
[main]
enabled = 0
I wrote a script to do this remotely. We are using individual accounts and I need to execute this command using SUDO:
for HOST in $(cat serverlist ) ; do echo $HOST; ssh -o ConnectTimeout=5 -oStrictHostKeyChecking=no $HOST -t 'sudo cp /etc/yum/pluginconf.d/rhnplugin.conf /etc/yum/pluginconf.d/rhnplugin.$(date +%F) ; sudo sed -i -e "s/1/0/g" /etc/yum/pluginconf.d/rhnplugin.conf ' ; done
I know it is a long line but why does it not work?
All individual commands work on their own
sudo cp /etc/yum/pluginconf.d/rhnplugin.conf /etc/yum/pluginconf.d/rhnplugin.$(date +%F)
sudo sed -i -e "s/1/0/g" /etc/yum/pluginconf.d/rhnplugin.conf
have tried escaping the special chars:
sudo sed -i -e "s\/1\/0\/g" /etc/yum/pluginconf.d/rhnplugin.conf
But I get an error all the time:
sed: -e expression #1, char 1: unknown command: `?'
Thanks for your help.
The sudo(1) command expects a pseudo-teletype (pty) and fails if it does not see one. Rewrite your command line to use su(1) instead. Use your local sudo(1) configuration to limit access to this script so only the select few can execute the script.
I actually found the answer to this question, or rather workaround. See the snippet below, where I got to -as root- ssh as me (szymonri) to other host, then invoke sed command as root in order to edit /etc/hosts file. All thanks to base64 magic.
ME=`echo -e "$(hostname -I | awk '{print $1}')\toverlord"`
B64ENC=`echo "sed -i 's/.*overlord/$ME/g' /etc/hosts" | base64`
su - szymonri sh -c "ssh jetson bash -c \\\"echo $B64ENC \| base64 --decode \| sudo bash \\\""
line: I"m obtaining m yown IP address as an /etc/hosts line
line: I'm base64 encoding sed command with the first line in it.
line: I'm invoking the SSH shenannigan, where I su as regular user, ssh to another box as the user, and use power of sudo to edit the file.

unexpected EOF while looking for matching `"'

The command works fine when I execute from command line. However It throws an error when I execute it from shell script
rsync -avz -e ssh --exclude-from=rsync.file --rsync-path="sudo rsync" ostnfe/ ubuntu#mask.compute-1.amazonaws.com:/var/www/ostnfe
Code from shell script:
CMD='rsync -avz -e ssh --exclude-from=rsync.file --rsync-path="sudo rsync" '$1'/ ubuntu#'$AMZ':/var/www/'$2
$CMD
error:
bash: -c: line 0: unexpected EOF while looking for matching `"'
bash: -c: line 1: syntax error: unexpected end of file
You could just use a shell function instead:
cmd () {
rsync -avz -e ssh --exclude-from=rsync.file --rsync-path="sudo rsync" $1/ ubuntu#$AMZ:/var/www/$2
}
# calling with args
cmd "$1" "$2"
# alternatively, calling through variable without args
VAR='eval cmd "$1" "$2"'
$VAR
Less hassle with escaping this way.
Update: Edited cmd() to represent the working solution.
Bad idea to store full command line in a string. Use BASH arrays instead:
CMD=(rsync -avz -e ssh --exclude-from=rsync.file "--rsync-path='sudo rsync'" "$1/ ubuntu#$AMZ:/var/www/$2")
"${CMD[#]}"
Please try following:
CMD=$(echo "rsync -avz -e ssh --exclude-from=rsync.file --rsync-path=\"sudo rsync\" $1/ubuntu#${AMZ}:/var/www/$2")
$CMD
check for any missing or extra space.

sed not working on remote machine

I'm trying to run a script on a remote server like so:
ssh root#cnc-02 'bash -c "
echo $SHELL;
cd /home/bldadmin/patch;
pwd;
echo '$int_ver_cnc';
echo '$rev_ver_cnc';
echo '$pre_ver_cnc';
cp -Rf RP_'$pre_ver_cnc'-'$int_ver_cnc' RP_'$int_ver_cnc'-'$rev_ver_cnc';
cd /home/bldadmin/patch/RP_'$int_ver_cnc'-'$rev_ver_cnc'/CSCONsap/data/twoway/manual;
rm rulePkg.zip;
mv cncrules-CNC60Test-1.48.0-1.49.0.zip rulePkg.zip;
cd /home/bldadmin/patch/RP_'$int_ver_cnc'-'$rev_ver_cnc';
find . -name install.sh.orig;
sed -e 's/^\(patchid=\)\(.*\)/\1\"1.47.0-1.48.0\"/g' -e 's/^\(fromVersion=\)\(.*\)/\1\"1.47.0\"/g' -e 's/^\(toVersion=\)\(.*\)/\1\"1.48.0\"/g' install.sh.orig >newfile.sh.orig;
"'
This is my script on my local machine. It will SSH to a remote machine and execute a list of commands. All the commands are executing but sed is not working. I'm getting the below error
"bash: -c: line 14: syntax error near unexpected token `(' bash: -c:
line 14: ` sed -e s/^(patchid=)(.*)/11.47.0-1.48.0/g -e
s/^(fromVersion=)(.*)/11.47.0/g -e s/^(toVersion=)(.*)/11.48.0/g
install.sh.orig >newfile.sh.orig;' "
The sed command when executed locally is working fine, I don't know what I am missing?
Instead of getting in a quoting headache save your script into a file script.sh
(use a sensible descriptive name) and run:
$ ssh root#cnc-02 'bash -s' < script.sh

Resources