0

I would like to run a su - <desired_user> but then also execute a command. I want to become that user in the new shell but just source a specific file.

The desired_user above is a batch user, shared across many regular users, and therefore nothing will work if put in the .profile, .bashrc, .bash_profile, etc.

For example, it would be combining the su and sourcing command into one alias that I can run.

(user1) $ whoami
user1
(user1) $ su - desiredUser
(desiredUser) $ 
(desiredUser) $ . custom_profile/my_custom_vars.ksh

Is there such an alias that I could use from user1 to accomplish both the su - <desired_user> and the sourcing? Once again, I cannot have anything in the .profile / .bashrc / .bash_profile as that would affect other users that also become this batch user.

Thank you!

jlarks32
  • 143
  • 1
  • 6

1 Answers1

1

With expect

Use the following expect script:

#!/usr/bin/expect 

log_user 0
spawn /bin/su - desiredUser
stty -echo
expect "*: "
send_user "Password: "
expect_user -re "(.*)\n"
send "$expect_out(1,string)\r"
stty echo
send ". custom_profile/my_custom_vars.ksh\r"
interact

The lines between stty -echo and stty echo are responsible for password handling. It's possible to include the password in the script itself. See this answer.

Just after sending the password the script sends the desired command as if you typed it. Then it lets you interact.

The solution is quick and dirty. In particular the script does not wait for a prompt, it sends . custom_profile/my_custom_vars.ksh right away. It should work, but if you need to send many commands this way, it may not be a reliable way. Grouping commands in a file and sending just one command to source the file seems better.


With --rcfile

I assume su - desiredUser runs bash. Bash supports --rcfile option:

When an interactive shell that is not a login shell is started, Bash reads and executes commands from ~/.bashrc, if that file exists. […] The --rcfile file option will force Bash to read and execute commands from file instead of ~/.bashrc.

(source, mind this)

The most straightforward way would be to provide bash --rcfile … after the -c option of su, but this option cannot be used to execute interactive programs (see man 1 su). To circumvent this, create a custom "shell", a wrapper:

customshell (needs to be executable):

#!/bin/sh
exec /bin/bash --rcfile /full/path/to/your/rc.file "$@"

Then invoke su like this:

su -s /full/path/to/customshell - desiredUser

Note this will source /full/path/to/your/rc.file instead of ~/.bashrc. To still source ~/.bashrc you need . ~/.bashrc as the first line of the rc.file.