sed not working on remote machine - linux

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

Related

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

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

Running jq on a remote machine over ssh and overwrite the file

I am trying to create a file from the output of jq command over ssh command.
ssh <server-Name> "jq '.credsStore = "ecr-login"' ~/.docker/config.json > ~/.docker/output.json "
It gives me following error:
bash: .docker/output.json: No such file or directory
Am I not running the command properly or is there any other problem?
ssh "$server" "bash -s" <<'EOF'
[[ -e ~/.docker/config.json ]] || {
echo "ERROR: $HOME/.docker/config.json does not exist on the remote server" >&2
exit 1
}
jq '.credsStore = "ecr-login"' \
<~/.docker/config.json \
>~/.docker/output.json
EOF

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.

How to log non-interactive bash command sent through ssh

I'm sending a command through ssh:
ssh server.org 'bash -s' << EOF
ls -al
whoami
uptime
EOF
How to log it in the system (remote server)? I'd like to log those commands in some file (.bash_history or /tmp/log).
I've tried to add the line below to sshd_config:
ForceCommand if [[ -z $SSH_ORIGINAL_COMMAND ]]; then bash; else echo "$SSH_ORIGINAL_COMMAND" >> .bash_history; bash -c "$SSH_ORIGINAL_COMMAND"; fi
But it logs "bash -s" only.
I'll appreciate any help.
When bash shell exits, bash reads and executes commands from the ~/.bash_logout file. Probably you can run the history command at the end in the .bash_logout(of the server) and save it to some location.
If it suffices to work with the given command, we can put the necessary additions to enable and log command history at the beginning and end, e. g.
ssh server.org bash <<EOF
set -o history
ls -al
whoami
uptime
history|sed 's/ *[0-9]* *//' >>~/.bash_history
EOF
Or we could put them into the awfully long ForceCommand line:
… if [[ "$SSH_ORIGINAL_COMMAND" == bash* ]]; then echo "set -o history"; cat; echo "history|sed 's/ *[0-9]* *//' >>~/.bash_history"; else cat; fi | bash -c "$SSH_ORIGINAL_COMMAND"; fi

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.

Resources