Run a shell script as a different user

249,629

Solution 1

To run your script as another user as one command, run:

/bin/su -c "/path/to/backup_db.sh /tmp/test" - postgres

Breaking it down:
 /bin/su : switch user
 -c "/path/to..." : command to run
 - : option to su, make it a login session (source profile for the user)
 postgres : user to become

I recommend always using full paths in scripts like this - you can't always guarantee that you'll be in the right directory when you su (maybe someone changed the homedir on you, who knows). I also always use the full path to su (/bin/su) because I'm paranoid. It's possible someone can edit your path and cause you to use a compromised version of su.

Solution 2

If the target user to run has nologin shelll defined, then you can use the -s option to specify the shell:

/bin/su -s /bin/bash -c '/path/to/your/script' testuser

See the following question: run script as user who has nologin shell

Solution 3

To automate this on a schedule you could put it in the user's crontab. Cron jobs won't get the full environment though, but it it might be better to put all the env variables you need in the script itself anyways.

To edit the user's crontab:

sudo crontab -u postgres -e

Solution 4

This should be an informative read -- setuid on shell scripts

If you run su with a "- username" argument sequence, it will make a login shell for the user to give the same environment as the user. Usually, used to quickly execute your script with your home environment from a different login.

Solution 5

Try the su manpage:

su -c script_run_as_postgres.sh - postgres

Alernately, you could use sudo to allow you to run just that comman as postgres without a password. It takes some setup in your /etc/sudoers, though.

Share:
249,629

Related videos on Youtube

yankeemike
Author by

yankeemike

Updated on September 17, 2022

Comments

  • yankeemike
    yankeemike over 1 year

    What's a good way of running a shell script as a different user. I'm using Debian etch, and I know which user I want to impersonate.

    If I was doing it manually, I would do:

    su postgres
    ./backup_db.sh /tmp/test
    exit
    

    Since I want to automate the process, I need a way to run backup_db.sh as postgres (inheriting the environment, etc)

    Thanks!

  • Dan Carley
    Dan Carley almost 15 years
    This can be useful, if you need to perform a series of actions. But bear in mind that most system service accounts shouldn't have valid home paths and shells.
  • zjffdu
    zjffdu about 12 years
    It will always require me type in password ? How can get round it ?
  • baumgart
    baumgart almost 12 years
    It will always require you to type in a password if you are running the command as a non-root user. If you want to avoid the password, you can configure sudo to allow that. HOWEVER - configuring sudo to allow a user to run su allows them to become any user. I would suggest creating a script for your command, setting the script permissions to 700 and owned by root, then configuring sudo to allow a user to run that single script.
  • JeanMertz
    JeanMertz about 11 years
    I believe - while this answer might work for the OP - it is not entirely correct. To my knowledge, using both - (or --login) together with --command, -c doesn't actually start a login session, because -c always forces a non-login shell.
  • saravanakumar
    saravanakumar almost 8 years
    Could you please explain more?
  • jonny
    jonny about 7 years
    Note: for portability, the - postgress should appear at the end of the command. From the man page: When - is used, it must be specified before any username. For portability it is recommended to use it as last option, before any username. The other forms (-l and --login) do not have this restriction.
  • nobody
    nobody over 3 years
    If you need a login shell, you can run this command with -i
  • Chang Zhao
    Chang Zhao over 2 years
    will this work on www-data user ?
  • baumgart
    baumgart over 2 years
    Yes, it will work for any user.