As part of my quest to preserve bashrc and vimrc when switching to non-root users, I plan on making some super ugly aliases to switch to other users, immediately execute some commands, and then drop me at their prompt.

Run an interactive bash subshell with initial commands without returning to the (“super”) shell immediately does not appear to answer my question. bash --init-file <(echo "ls; pwd; a=7") works as expected; but sudo bash --init-file <(echo "ls; pwd; a=7") does not (echo $a returns nothing; nothing is printed to the terminal from ls or pwd).

Why does the first command work, but not the second? How can I make a bash command that executes commands in other user's shell which persistently change environment variables and then access that shell? Note that this is more about making this work for switching to other non-root users; I already have a different solution that works for root.

1 Answer 1

% echo <(echo "ls; pwd; a=7")
% bash
$ echo <(echo "ls; pwd; a=7")

so the <(...) form is actually a path to a file descriptor specific to the shell that may not be available to other processes; the bash one in particular is actually a pipe:

$ function hmm() { ls -al $1; }
$ hmm <(echo pwd)
lr-x------ 1 jhqdoe jhqdoe 64 Aug 21 14:58 /dev/fd/63 -> pipe:[910134]

sudo takes pains for security reasons to close all these file descriptors by default (see --close-from option docs in sudo(8)). You might be able to wiggle one of these file descriptors through (if security policies allow it and you are okay with the risk) via the closefrom_override and then also --close-from, maybe.

Another method would be to use expect and then turn things over to the user after running some commands:

#!/usr/bin/env expect
spawn -noecho bash
expect -ex {$}
send "pwd\r"
expect -ex {$}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .