LinuxQuestions.org
Latest LQ Deal: Complete CCNA, CCNP & Red Hat Certification Training Bundle
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-10-2012, 01:02 AM   #1
theonislair
LQ Newbie
 
Registered: Oct 2011
Distribution: Fedora, CentOS, RHEL
Posts: 12

Rep: Reputation: Disabled
How do I perform commands in a bash script as a different user?


Hi. This is sort of a follow-up (but entirely new) question to one I posted yesterday.

Code:
#!/bin/bash
[... some checks ...]
sudo su - $1

HOMEURL="define(\'WP_HOME\'\, \'http://$HOSTNAME/~$USER\');"
SITEURL="define(\'WP_SITEURL\'\, \'http://$HOSTNAME/~$USER\');"
PUBHTML="$HOME/public_html"

cp $PUBHTML/wp-config.php $PUBHTML/wp-config.php.notmp

sed "/DB_COLLATE/ a\
$HOMEURL\n\
$SITEURL\
" $PUBHTML/wp-config.php > $PUBHTML/wp-config.php.tmp

cat $PUBHTML/wp-config.php.tmp > $PUBHTML/wp-config.php
rm $PUBHTML/wp-config.php.tmp
The code above works (thanks to this and pixellany), but not to the extent I want it to. The script has one possible argument (a username) that I'd like the shell to switch to, perform the cp, sed, cat and rm then return back to the original shell. $HOME and $USER need to return as the *argument* username's homedir and username, not the user performing it. I've tried double quotes (escaping the other double quotes with \), back ticks and single quotes (which are already escaped as literal).. what can I do to make this work? When the

Code:
sudo su - $1
is performed, the rest of the commands aren't performed as the user. Considering security I can't pass it off as a secondary script that the user performs, it all needs to be within one script that a (near) super user performs.
Code:
su -c "command" $1
won't work in this case either, unfortunately.

Last edited by theonislair; 06-10-2012 at 01:12 AM.
 
Old 06-10-2012, 01:52 AM   #2
jlinkels
Senior Member
 
Registered: Oct 2003
Location: Bonaire, Leeuwarden
Distribution: Debian /Jessie/Stretch/Sid, Linux Mint DE
Posts: 4,703

Rep: Reputation: 731Reputation: 731Reputation: 731Reputation: 731Reputation: 731Reputation: 731Reputation: 731
Code:
sudo -u otheruser /path/to/command parm1 parm2
jlinkels
 
Old 06-10-2012, 02:20 AM   #3
theonislair
LQ Newbie
 
Registered: Oct 2011
Distribution: Fedora, CentOS, RHEL
Posts: 12

Original Poster
Rep: Reputation: Disabled
While I appreciate the gesture; that didn't work.
 
Old 06-10-2012, 02:35 AM   #4
jlinkels
Senior Member
 
Registered: Oct 2003
Location: Bonaire, Leeuwarden
Distribution: Debian /Jessie/Stretch/Sid, Linux Mint DE
Posts: 4,703

Rep: Reputation: 731Reputation: 731Reputation: 731Reputation: 731Reputation: 731Reputation: 731Reputation: 731
Quote:
Originally Posted by theonislair View Post
that didn't work.
That doesn't say anything. How it doesn't work?

jlinkels
 
Old 06-10-2012, 11:47 AM   #5
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian + kde 4 / 5
Posts: 6,834

Rep: Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976
You do realize that you also have to make sure that sudo is configured to allow that user to run that command, right?
 
Old 06-10-2012, 02:10 PM   #6
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 946Reputation: 946Reputation: 946Reputation: 946Reputation: 946Reputation: 946Reputation: 946Reputation: 946
Quote:
Originally Posted by theonislair View Post
I'd like the shell to switch to, perform the cp, sed, cat and rm then return back to the original shell. $HOME and $USER need to return as the *argument* username's homedir and username, not the user performing it.
Code:
#!/bin/bash
if [ $# -lt 1 ] || [ "$*" = "-h" ] || [ "$*" = "--help" ]; then
    exec >&2
    echo ""
    echo "Usage: $0 -h | --help"
    echo "       $0 USER"
    echo ""
    exit 0
fi

User="$1"
shift 1
if [ -z "$User" ]; then
    echo "No user specified." >&2
    exit 1
fi
if ! id -u "$User" &>/dev/null ; then
    echo "$User: No such user." >&2
    exit 1
fi

Home="$(getent passwd "$User" | cut -d : -f 6)" || exit $?
if [ -z "$Home" ]; then
    echo "$User: This user has no known home directory." >&2
    exit 1
fi
if [ ! -d "$Home" ]; then
    echo "$User: Cannot locate user home directory ($Home)." >&2
    exit 1
fi

# Edit as $User:
sudo -u "$User" -- sed -e '/DB_COLLATE/ a\define(\x27WP_HOME\x27\, \x27http://'"$HOSTNAME/~$User"'\x27);\ndefine(\x27WP_SITEURL\x27\, \x27http://'"$HOSTNAME/~$User"'\x27);' -i "$Home/public_html/wp-config.php" || exit $?

# Back as original user ...
The sed expression is a bit messy; you might wish to test it first. Drop the -i option to have it only output the result instead of modifying the specified file.

If you need to do a more complex edit, I recommend putting that part in a separate scriptlet. You can do
Code:
sudo -u "$User" -- bash -c '
    ... scriptlet ...
' || exit $?
but the quoting inside is pretty hairy. Note that if you want the helper script to be non-executable, you can always do
Code:
sudo -u "$User" -- bash -c "export USER='$User'; export HOME='$Home'; . /path/to/helper" || exit $?
The || exit $? bits I've liberally sprinkled here and there means "but if that fails, abort the script".

Note the getent passwd "$User" | cut -d : -f 6 expression: I believe it is the most portable easy way to find the user home directory. It should work even when using a remote user database. It does work fine on all machines I tested, even on SunOS 5.10. You could always rely on Bash tilde expansion, but applying the expansion from a string is a bit difficult to do reliably; all the ways I could think of just now would involve eval.
 
1 members found this post helpful.
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Running root executable commands within user bash script tommyttt Linux - Software 5 08-28-2011 09:38 PM
SSH connection from BASH script stops further BASH script commands tardis1 Linux - Newbie 3 12-06-2010 09:56 AM
script Q : how do I force bash to perform the math? kevinyeandel Linux - Newbie 4 02-20-2009 03:35 AM
helping me in a bash script that perform a "select" menus Task adam_blackice Programming 5 09-15-2007 02:09 PM
Using vi commands in a bash script tiger Programming 1 05-21-2001 06:08 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 11:49 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration