skip to Main Content

I have a .sh script that runs changes to PostgreSQL DB, and provides a report of those changes. As an output from the script a report.csv file is produced. The server has multiple users that are only allowed to read the file. At the end of the script I want to zip and archive it (.csv and .zip files are both the purposed outcome). These directives require using sudo rights to run.
My question is how to arrange the shell commands semantically correct so that I use sudo as less as possible?

I cannot run the whole script as sudo since it uses psql access and that would change the user running the db access to root.

#!/bin/bash
sudo chmod 440 /tmp/$REPORT_FILE

# Move to archive folder and rename
sudo mv /tmp/$REPORT_FILE/$ARCHIVE_DIR$/$REPORT_NAME

cd $ARHIVE_DIR
sudo zip ${REPORT_ZIP_NAME} {REPORT_NAME}
sudo chmod 440 ${REPORT_ZIP_NAME}
rm $REPORT_NAME

2

Answers


  1. For limiting the sudo calls to one you could create a temporary directory, do your stuff, and then move the files:

    #!/bin/bash
    
    REPORT_NAME=myReportName
    REPORT_ZIP_NAME=something.zip
    ARCHIVE_DIR=/some/path
    
    tempdir=$(mktemp -d)
    chmod 700 "$tempdir"
    
    # ... "$REPORT_FILE" is created in "$tempdir" one way or another ...
    
    pushd "$tempdir" > /dev/null
    
    mv "$REPORT_FILE" "$REPORT_NAME"
    zip "$REPORT_ZIP_NAME" "$REPORT_NAME"
    
    chmod 440 *
    sudo mv * "$ARCHIVE_DIR"/
    
    popd > /dev/null
    
    rmdir "$tempdir"
    

    side-notes: you should always double-quote your var expansions; also, using uppercase varnames for local variables is risky because it might conflict with external or builtin variables (for ex. REPLY, SECONDS, etc…)

    Login or Signup to reply.
  2. A common arrangement is to run the entire script as sudo, but have it drop its privileges once it’s done.

    #!/bin/bash
    
    # Exit with an error code if one of these commands fail
    set -e
    
    chmod 440 /tmp/"$REPORT_FILE"
    # this line had an error; did you mean this?
    mv /tmp/"$REPORT_FILE" "/$ARCHIVE_DIR$/$REPORT_NAME"
    
    cd "$ARHIVE_DIR"
    # I'm guessing REPORT_NAME was supposed to be $REPORT_NAME?
    zip "$REPORT_ZIP_NAME" "$REPORT_NAME"
    chmod 440 "$REPORT_ZIP_NAME"
    rm "$REPORT_NAME"
    
    exec su - "$SUDO_USER" -c 'psql blah blah ...'
    

    The set -e is a bit of a kludge, but I did not want to add explicit error checking for each command which requires privileged access.

    Notice also When to wrap quotes around a shell variable

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search