I need to script a way to do the following (note all is done on the local machine as root):
runuser -l user1 -c 'ssh localhost' &
runuser -l user1 -c 'systemctl --user list-units'
The first command should be run as root. The end goal is to log in as "user1" so that if any user ran who
"user1" will appear in this list. Noticed how the first command is backgrounded before the next command is run.
The next command should be run as root as well, NOT user1.
Problem: These commands run fine when run separately, but when run in a script "user1" never appears to show up when running who
. Here is my script
#!/bin/bash
echo "[ ] Becoming user1"
runuser -l user1 -c 'ssh -q localhost 2>/dev/null' &
echo
sleep 1
echo "[ ] Running systemctl --user commands as root."
runuser -l user 1 -c 'systemctl --user list-units'
echo "[ ] Killing active ssh sessions."
kill $(ps aux | grep ssh | grep "^user1.*" | grep localhost | awk '{print$2}') 2>/dev/null
echo "[ ] Done."
When running the script it looks like the script is able to ssh into the system but who
does not show the user logged in, nor do any ps aux
output show a ssh session. Note: I commented out the kill
line to confirm if the process stays, which I do not see it at all.
How do I make the bash script fork two processes. Process 1 goal is to login as "user1" and wait. Then process 2 is to perform commands as root while user1 is logged in?
CodePudding user response:
My goal is to run systemctl --user commands as root via script. If your familiar with systemctl --user domain, there is no way to manage systemctl --user units, without the user being logged in via traditional methods (ssh, direct terminal, or gui). I cannot "su - user1" as root either. So I want to force an ssh session as root to the vdns11 user via runuser commands. Once the user is authenticated and shows up via who I can run systemctl --user commands. How can I keep the ssh session active in my code?
With this additional info, the question essentially boils down to 'How can I start and background an interactive ssh session?'.
You could use script
for that. It can be used to trick applications into thinking they are being run interactively:
echo "[ ] Starting SSH session in background"
runuser -l user1 -c "script -c 'ssh localhost'" &>/dev/null &
pid=$!
...
echo "[ ] Killing active SSH session"
kill ${pid}
Original answer before OP provided additional details (for future reference):
Let's dissect what is going on here.
I assume you start your script as root:
echo "[ ] Becoming user1"
runuser -l user1 -c 'ssh -q localhost 2>/dev/null' &
So root
runs runuser -l user1 -c '...'
, which itself runs ssh -q localhost 2>/dev/null
as user1
. All this takes place in the background due to &
.
ssh
will print Pseudo-terminal will not be allocated because stdin is not a terminal.
(hidden due to 2>/dev/null
) and immediately exit. That's why you don't see anything when running who
or when running ps
.
Your echo
says [ ] Becoming user1, which is quite different from what's happening.
sleep 1
The script sleeps for a second. Nothing wrong with that.
echo "[ ] Running systemctl --user commands as root."
#runuser -l user 1 -c 'systemctl --user list-units'
# ^ typo!
runuser -l user1 -c 'systemctl --user list-units'
Ignoring the typo, root
again runs runuser
, which itself runs systemctl --user list-units
as user1
this time.
Your echo
says [ ] Running systemctl --user commands as root., but actually you are running systemctl --user list-units
as user1
as explained above.
echo "[ ] Killing active ssh sessions."
kill $(ps aux | grep ssh | grep "^user1.*" | grep localhost | awk '{print$2}') 2>/dev/null
This would kill the ssh
process that had been started at the beginning of the script, but it already exited, so this does nothing. As a side note, this could be accomplished a lot easier:
echo "[ ] Becoming user1"
runuser -l user1 -c 'ssh -q localhost 2>/dev/null' &
pid=$!
...
echo "[ ] Killing active ssh sessions."
kill $(pgrep -P $pid)
So this should give you a better understanding about what the script actually does, but between the goals you described and the conflicting echo
s within the script it's really hard to figure out where this is supposed to be going.