0

I wrote a bash command (that's working) to update an IP address on two remote Pihole DNS servers and restart DNS:

NEW_IP=$(hostname -I); \
ssh pi@raspberrypi3 sudo sed -i "s/172.*/'$NEW_IP'nuc8-pc-wsl.localdomain/g" \
  /etc/pihole/custom.list; \
ssh pi@raspberrypi3 sudo pihole restartdns; \
ssh pi@raspberrypi4 sudo sed -i "s/172.*/'$NEW_IP'nuc8-pc-wsl.localdomain/g" \
  /etc/pihole/custom.list; \
ssh pi@raspberrypi4 sudo pihole restartdns

It's great to have it functioning, but it seems like I shouldn't have to repeat commands like:

sudo sed -i "s/172.*/'$NEW_IP'nuc8-pc-wsl.localdomain/g" /etc/pihole/custom.list

and

sudo pihole restartdns

Loading these commands into variables has resulted in requests for the ssh password from the server -- so that can't be right since I have public key authentication setup. I'm already using pairs of single, and double quotes -- so, I'm not sure how to structure this command to be more compact.

I also tried to use, after each sed command:

&& pihole restartdns

so that one ssh would execute both commands on the host, but the response was:

bash: pihole: command not found

Which I take it to mean that part of the command attempted to run on my local machine rather than the server. How does one go about making a command like this more elegant by avoiding repetition?

bnhf
  • 41
  • 4

1 Answers1

0

Suggesting to combine all ssh commands into single multi-lined command:

NEW_IP=$(hostname -I); 

set -x  #enable debug trace
ssh pi@raspberrypi3  <<< '
sudo -i
sed -i "s/172.*/'$NEW_IP'nuc8-pc-wsl.localdomain/g" /etc/pihole/custom.list
pihole restartdns
sed -i "s/172.*/'$NEW_IP'nuc8-pc-wsl.localdomain/g" /etc/pihole/custom.list
pihole restartdns
'
set +x  #disable debug trace
Dudi Boy
  • 4,551
  • 1
  • 15
  • 30
  • It's not well-defined that `sudo -i` will receive the rest of stdin. I would suggest a nested heredoc to make it unambiguous that the remaining commands are fed to the stdin of the shell started by `sudo` (though I'm not convinced that it's a good idea to run an interactive subshell at all; one `sudo` per subprocess is a little bit of performance hit, but it'll make the logging much clearer for whoever's trying to reconstruct what was done after-the-fact). – Charles Duffy Mar 20 '22 at 23:46
  • Also, the `set -x` trace isn't going to be very useful here, because herestring contents isn't logged, and you aren't enabling `set -x` for the other shell on the remote side of the ssh connection. – Charles Duffy Mar 20 '22 at 23:47
  • Thanks for the input Charles. Everything I've been working on ends up being nearly as long, and as-is it only takes a few seconds to run. Combining making the command more readable with newlines and your comment about more straightforward logging -- I think I'll go with the command as edited above. – bnhf Mar 21 '22 at 02:12
  • crontab -e didn't like the escaped newlines after @reboot, so its back to my original one-liner for that. – bnhf Mar 21 '22 at 02:33