简体   繁体   中英

Bash script not executing command properly when run from script

I have a shell script as follows

#!/bin/bash
USER=someuser
HOSTNAMEORIP=somehostname
SCRIPT="/etc/rc.d/netif restart && /etc/rc.d/routing restart"
su -c "ssh -l ${USER} ${HOSTNAMEORIP} ${SCRIPT}" -s /bin/sh someotheruser

If I login to the machine and just run the "/etc/rc.d/netif restart && /etc/rc.d/routing restart" it works. But if i run the entire script above, i get sh: 1: /etc/rc.d/routing: not found as if it's not handling the script part the same. I can even use the above script without a user like this

#!/bin/bash
USER=someuser
HOSTNAMEORIP=somehostname
SCRIPT="/etc/rc.d/netif restart && /etc/rc.d/routing restart"
ssh -l ${USER} ${HOSTNAMEORIP} ${SCRIPT}

And it works but I need to use su -c <command> -s /bin/sh user because another application is calling the script and the user associated is the only one with ssh-key login/no password to the other machine.

How can i make su -c "ssh -l ${USER} ${HOSTNAMEORIP} ${SCRIPT}" -s /bin/sh someotheruser run the script properly in this use case?

Let's just work through it. This command:

su -c "ssh -l ${USER} ${HOSTNAMEORIP} ${SCRIPT}" -s /bin/sh someotheruser

Will execute this string as a shell command:

ssh -l someuser somehostname /etc/rc.d/netif restart && /etc/rc.d/routing restart

This is clearly wrong, and will fail with the same error.

To fix it, let's fix the command and work backwards. You should be executing

ssh -l someuser somehostname '/etc/rc.d/netif restart && /etc/rc.d/routing restart'

Therefore, you can update your script like this:

#!/bin/bash
USER=someuser
HOSTNAMEORIP=somehostname
SCRIPT="/etc/rc.d/netif restart && /etc/rc.d/routing restart"
su -c "ssh -l ${USER} ${HOSTNAMEORIP} '${SCRIPT}'" -s /bin/sh someotheruser
#                                     ^---      ^---

Note that this hinges on the fact that $SCRIPT does not contain embedded single quotes. If does or if you don't know, you can use $(printf "%q" "$SCRIPT") instead of '$SCRIPT' in the embedded string to have bash auto-escape it.

Or you can switch to sudo . Since it uses safe and robust execve(2) semantics instead of system(3) semantics, you wouldn't have to nest escaping:

sudo -u someotheruser ssh -l "$USER" "$HOSTNAMEORIP" "$SCRIPT"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM