Switch User in within a Shell Script

Hi Experts,

I'm trying to write a shell script to stop few things where i have to use another user to execute a command. Otherwise it will not work.

Your help is really appreciated

Thanks,

1 Like

Try:

su - user -c "command"
2 Likes

A search on unix forum gave me these results:

1 Like

Hi,

The following command is prompting for the password. Is there anyway to specify the password and it does not promt again?

su - user -c "command"

  • You an wrap su in an expect script (exposing the password a bit),
  • or set up passwordless login for you-here to him-here using rsh/remsh/rexec/ssh/ssh2,
  • or hit some custom service like a web site running under that user
  • or have some sort of server/daemon process running or frequent cron under that user looking for some sort of message (file, named pipe, email, tcp/udp IP port or other similar network facility like netbui) to trigger the commands you need,
  • or write an setuid bit friendly C program or restricted shell owned by other id that can be executed by you. Setuid is not shell friendly, as it drops LD_LIBRARY_PATH or the like used for dynamic linking and must be compiled staticly or with -R to give it library path for every necessary lib file.
1 Like

I have no issues with the exposing the password. What would be the exact command though?

Is this right? >> su - user/password -c "command"

Man Page for su (OpenSolaris Section 1m) - The UNIX and Linux Forums

Expect-5.43.0

#!/usr/local/bin/expect --
# Name: autoexpect - generate an Expect script from watching a session
#
# Description:
#
# Given a program name, autoexpect will run that program. Otherwise
# autoexpect will start a shell. Interact as desired. When done, exit
# the program or shell. Autoexpect will create a script that reproduces
# your interactions. By default, the script is named script.exp.
# See the man page for more info.
#
# Author: Don Libes, NIST
# Date: June 30 1995
# Version: 1.4

1 Like

I think I will go with the SSH kyes exchange from one user to another so the process can be worked.

Correct me If I'm wrong. By exchanging ssh keys, it will do the su without the password prompt or it will only work if I do ssh command?

One way if you don't want to execute the user's login profile.

su user -c "command"

Depending on your environment I find it works best using "remsh" with a suitable ".rhosts" file - even within the same computer.

remsh localhost -l username -n "command"

The su needs a password for everyone but root.

  • The su logname - -c "commands" as root or with password interaction is equivalent to
  • old, security-dissed .rhosts entries with: 'rsh localhost -l logname [ -n if no input ] "commands"' is equivalent to
  • matching ssh keys and 'ssh localhost -l logname [ -n if no input ] "commands"' is equivalent to
  • matching ssh2 keys and 'ssh2 localhost -l logname [ -n if no input ] "commands"'.

The last is most defensible to a security auditor, and a bit more secure even if you do not read all the instructions! BTW, permissions on control files are critical to all the but su! Sometimes, give or take what shell runs "commands" (unless they all got to use $SHELL) and the running of the remote .profile or .kshrc or whatever.

Hey DGPickett,

A question to clarify. I need to execute 4 different commands with 4 different users so it means that I have to switch the users 4 times. As per my understanding, I can use the following commands.

set LOG='ABC/ABC/ABC.LOG

1 sudo/su - user -c "command" >> $LOG
exit

  1. sudo/su - user2 -c "comand" >> $LOG
    exit

  2. sudo/su - user3 -c "command" >> $LOG
    exit

  3. sudo/su - user4 -c "command" >> $LOG

By doing that, each user have it's own environment veriables so do I need to setup the envs or it will catch it own its own.

One of the commands, I want to add grep command to one of the processes. If it finds, kill it. how can I get a specific running process and kill it if finds?

Your help is really appreciated
Thanks,
Afi

You don't need to use exit the sudo/su -c command will exit when the command completes:

sudo -u user1 ksh -c /usr/local/bin/myapp >> $LOG 2>&1
sudo -u user2 ksh -c "ps -ef | grep [m]yapp | awk '{print $2}' | xargs -r kill"
su user1 "-c /usr/local/bin/myapp" >> $LOG 2>&1
su user2 "-c ps -ef | grep [m]yapp | awk '{print \$2}' | xargs -r kill"

I'm guessing that the following lines are two different commands.

  1. sudo -u user1 ksh -c /usr/local/bin/myapp >> $LOG 2>&1
  2. sudo -u user2 ksh -c "ps -ef | grep [m]yapp | awk '{print $2}' | xargs -r kill"

Do I need to add (>> $LOG) for the 2nd line if I need to capture it in the logs?

Thanks,

Yes these are two seperate commands (as examples of running single program or mini script as a pipeline).

You would need to capture the output of the kill command (typically kill dosn't output anything to stdout but best to redirect this and stderr to your logfile). BTW the ksh -c part is only needed when running script commands and the following is sufficient:

sudo -u user1 /usr/local/bin/myapp >> $LOG 2>&1
sudo -u user2 ksh -c "ps -ef | grep [m]yapp | awk '{print $2}' | xargs -r kill" >> $LOG 2>&1

Edit: Note that the redirection is happening outside of the command invoked by sudo (ie not within the quotes in the 2nd example) so the LOG file will be written by the logged in user (not user1 or user2). If you get anything much more complex than a 1 liner best to write a shell script and invoke that with sudo. Also this way you can restrict the use of sudo for this particular script and not allow a user to do anything they want as user2.

What does a command "(2>&1)" does?

I will not be running any scripts so I guess I can run the 2nd command as follow assuming that I have to kill XYZ process if running..

sudo -u user2 "ps -ef | grep XYZ | awk '{print $2}' | xargs -r kill" >> $LOG 2>&1

Yes that should be fine, just grep for [X]YZ instead.

The square brackets tell grep match any of the following single characters (a single X here). So this will find XYZ, but because the command line of the grep has the square brackets, grep wont match it's self and we avoid killing the grep command. eg:

# ps -ef | grep ntpd
    root  278664  209062   0   Oct 03      -  1:03 /usr/sbin/xntpd 
    root 1540282  659564   0 09:11:58 pts/29  0:00 grep ntpd
# ps -ef | grep [n]tpd
    root  278664  209062   0   Oct 03      -  1:03 /usr/sbin/xntpd

2>&1 means redirect standard error (the stream most error messages are printed on) to the same location as standard output. This will allow your log to capture both normal program output and any error messages on the error stream.

1 Like

Is the following command will show up in a logs if [X]YZ is running? The actual ouput of ps -ef |grep XYZ ?

I want to kill it if running. I'm assuming that the commad "{print $2}" print the PID of the XYZ process and kill it.

Thanks,
Afi