SED in remote SUDO ssh script - linux

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.

Related

how to cat file from local to remote while using sudo without typing password

I'm trying to cat the local file to remote file and use diff to compare the difference of the two files.
I need to use sudo to run the command and hope it can run automaticall wihtout typing password manually.
The followings are my code now.
cat
cat password.txt | sshpass -p ${USER_PASSWORD} ssh -o StrictHostKeyChecking=no -o "ConnectTimeout 5" -tt ${USER_NAME}#${PEER_IPADDRESS[${i}]} "sudo cat > ${DIR_SET}${FILE_NAME}.txt"< ${DIR_SET}${FILE_NAME}.txt
diff
DIFF=$(diff ${DIR_SET}${FILE_NAME}.txt <(cat password.txt | sshpass -p ${USER_PASSWORD} ssh -o StrictHostKeyChecking=no -o "ConnectTimeout 5" -tt ${USER_NAME}#${PEER_IPADDRESS[${i}]} "sudo cat ${DIR_SET}${FILE_NAME}.txt"))
At first, I try to use pipeline to cat and diff the local file to the remote one.
However, it seems that to use sudo without typing password also need to use the vertical pipe.
My question is:
1.Is it possible to use two pipeline in one line code, and how to run them seperatley to make my code work.
2.Are there any way to use sudo without typing password or to use cat/diff without useing pipeline.
Thank you very much.

Bash - write to visudo

I want to write something to visduo and I can't write to /etc/sudoers
for SERVER in $(cat some.txt); do
ssh -q -o StrictHostKeyChecking=no root#$SERVER '
echo 'm2madm ALL=(ALL:ALL) NOPASSWD:/sbin/iptables -L' | sudo EDITOR='tee -a' visudo
'
problem is with '
but I really don't know what I should do, can you help me please?
the output is:
domain_check.sh: line 25: syntax error near unexpected token `('
domain_check.sh: line 25: `echo ('m2madm ALL=(ALL:ALL) NOPASSWD:/sbin/iptables -L' | sudo EDITOR='tee -a' visudo)'
If you want to use variables in the string you sent trough ssh, enclose that string with ". Within the string you should use a single quote ', or escape every double quote \".
Your problem occurs because you "close" the string before you're meaning to. The following should work.
for SERVER in $(cat some.txt); do
ssh -q -o StrictHostKeyChecking=no root#$SERVER "
echo 'm2madm ALL=(ALL:ALL) NOPASSWD:/sbin/iptables -L' | sudo EDITOR='tee -a' visudo
"
done
P.s. there is a shell spell check site in which you can test your code. I don't know which, but I will add it as a comment below my answer.

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.

How to suppress comments in linux ssh here script

When using here script in a linux bash to run commands on a remote server all the lines are printed. How can the comments be suppressed?
The output of the below code should be:
ls
... (whatever is in this folder)
echo -e this is a test\ndone
this is a testndone
exit
Is this possible?
The reason for doing this is that the commands and comments are more complex making the output hard to read. That should be prettier.
#!/bin/bash
ssh -tt hogan#123.123.123.123 <<EOF
# this line get printed
ls
# and this comment also
echo -e this is a test\ndone
# exit ssh
exit
EOF
#end of script
I usually use sed to filter out comments and blank lines. The following will also strip comments that follow a command on the same line:
#!/bin/bash
sed 's/[[:blank:]]*#.*//; /^$/d' <<EOF | ssh -tt hogan#123.123.123.123
# this line get printed
ls
# and this comment also
echo -e "this is a test\ndone"
# exit ssh
exit
EOF
After the command try typing
| grep -v "^[[:space:]]*#"
so for example,
cat temp.txt | grep -v "^[[:space:]]*#"
I think you might be asking for this
grep -v '^[[:space:]]*#' <<EOF | ssh -tt hogan#123.123.123.123
# this line get printed
ls
# and this comment also
echo -e this is a test\ndone
# exit ssh
exit
EOF

Command wont run in script

I am trying to run a command in a shell script but it is not working.
Out side of the script in the shell I can run the following command on the needed host. The file is created with the correct information inside.
sudo cat /etc/shadow | cut -d: -f1,8 | sed /:$/d > /tmp/expirelist.txt
When the command is run in my script I first ssh over then run the command but I get the following error.
[batch#testserver01 bin]$ checkP.sh
Testserver02
/usr/local/bin/checkP.sh: line 7: /tmp/expirelist.txt: Permission denied
Here is a part of the script. I have tried using ssh -o
#!/bin/bash
for SERVER in `cat /admin/lists/testlist`
do
echo $SERVER
ssh $SERVER sudo cat /etc/shadow | cut -d: -f1,8 | sed /:$/d > /tmp/expirelist.txt
...
What is causing the Permission denied error?
Don't use hardcoded temporary filenames -- when you do, it means that if one user (say, your development account) already ran this script and left a file named /tmp/expirelist.txt behind, no other user can run the same script.
tempfile=$(mktemp -t expirelist.XXXXXX)
ssh "$SERVER" sudo cat /etc/shadow | cut -d: -f1,8 | sed /:$/d >"$tempfile"
By using mktemp, you guarantee that each invocation will use a new, distinct, and previously-nonexisting temporary file, preventing any chance of conflict.
By the way -- if you want the file to be created on the remote system rather than the local system, you'd want to do this instead:
ssh "$SERVER" <<'EOF'
tempfile=$(mktemp -t expirelist.XXXXXX)
sudo cat /etc/shadow | cut -d: -f1,8 | sed /:$/d >"$tempfile"
EOF
I'm not sure about this, but you could be running into an issue with having the 'sudo' within your script. You could try removing the 'sudo' from the script, and running it like this:
$ sudo checkP.sh

Resources