0

I wanted to make a hardcoded script automatically run as root and I came across this:

#!/bin/bash
cat >/tmp/convert.sh <<EOF

some script here

EOF
chmod +x /tmp/convert.sh
sudo /tmp/convert.sh
rm /tmp/convert.sh

Although this works well, the shell seems to read the script while cat stores the file and emits some messages. Is there a better way to do this so the shell won't read the script before it runs?

3 Answers3

2

The script presented is a wrapper that writes a separate script in /tmp and uses the sudo command to execute that with elevated privileges. The reason to do it that way would be to accommodate the possibility that root cannot access the original file, which might be the case if the file resides on a network file system, if mandatory access controls (e.g. SELinux) prevent it, or perhaps for other reasons.

Is there a better way to do this so the shell won't read the script before it runs?

Of course the shell needs to read the script in order to run it, so I take you to be asking about the creation of an additional script. That is necessary if you want to accommodate the possibility that root cannot access the original script, though the example implementation is dangerously poor. If you aren't worried about that possibility then no, it is not necessary to make a separate script. In that case, one might instead do this:

#!/bin/bash

[[ $EUID -eq 0 ]] || exec sudo /bin/bash -c "${BASH_SOURCE[0]}"

some script here

That checks whether the script is running with effective user ID 0, and if not, uses sudo to relaunch itself. It does not depend on the original script to be marked executable. Like the example script, this will be subject to authentication and authorization via sudo, which is the only thing that makes the automatic privilege elevation at all reasonable as far as I am concerned.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
2

In Bash I recommend using functions and declare -f to transfer properly escaped work to be done.

#!/bin/bash

work() {
   some script here
   normally escaped
}

{
   declare -p var1 var2     # transfer variables if any are needed
   declare -f work          # let bash handle the hard escaping
   echo 'work "$@"'         # actually call the 'work' function
} | sudo bash -s            # why create a file? Just forward to shell.
KamilCuk
  • 120,984
  • 8
  • 59
  • 111
0

John is 100% correct with his answer to this, but I want to note one other possibility for using a heredoc to generate anther script. There could be variable substitutions in the heredoc. Even if the same thing could be done somehow without substituting variables during the heredoc stage you should review the code and test it thoroughly to make sure you're not introducing a bug by refactoring out that "oddity".

chicks
  • 2,393
  • 3
  • 24
  • 40