0

This would have probably been answered by Keep running a script via ssh, if I didn't have to run a command as superuser. Let me try with an example: say on my server, I have this script as ~/testsleep.sh, which is also chmod +x:

#!/usr/bin/env bash

logger Pre sleep: "$USER" / "$USERNAME" / "$1"

sleep 5

logger Post sleep: "$USER" / "$USERNAME" / "$1"

I want to have logger log to /var/log/syslog, since via ssh I'm likely to lose stdout/stderr.

Say I run this on my local PC, logged in via ssh to the remote server:

server$ readlink -f ~/testsleep.sh 
/home/user/testsleep.sh

server$ $ ls -la testsleep.sh 
-rwxr-xr-x 1 user user 126 2015-02-05 13:35 testsleep.sh

server$ sudo /home/user/testsleep.sh some_argument
sudo: unable to execute /home/user/testsleep.sh: No such file or directory

The first problem is that I cannot run the script directly with sudo, even if it is executable; I think this has to do with "your current shell is running under your regular user ID ... and there is no way to grant it root access" Execute a shell script in current shell with sudo permission - Stack Overflow

Ok, fine, I'll run sudo bash - this looks more like it:

server$ sudo bash /home/user/testsleep.sh some_argument

server$ tail -2 /var/log/syslog
Feb  5 13:40:48 user user: Pre sleep: root / root / some_argument
Feb  5 13:40:53 user user: Post sleep: root / root / some_argument

So, apparently the script does log in syslog, and sees root as $USER; as intended. So far, so good.

Now, I'd like to run this script as a process on the server, right before I exit my ssh terminal session. I guess I'd do this:

server$ sudo bash /home/user/testsleep.sh from_end & exit
[1] 6293
logout
Connection to 127.1.100.99 closed.
local$

If I log back in into the server, and check syslog again, I can see that there is no log from this last, "exiting" invocation:

# this `grep` will print the filename, if file doesn't contain the match:

server$ grep --files-without-match 'from_end' /var/log/syslog
/var/log/syslog
server$ tail -2 /var/log/syslog
Feb  5 13:40:48 mypc user: Pre sleep: root / root / some_argument
Feb  5 13:40:53 mypc user: Post sleep: root / root / some_argument

So, my question is - how can I run this script as a process, under sudo on the server - but invoked from an ssh shell, and right before exiting it; so that it runs (in this case, confirmed by writing to the syslog)?

0

1 Answer 1

1

You need to disown the job so it doesn't get killed when the connection is "hung up":

sudo bash /home/user/testsleep.sh from_end & sleep 1; disown -h; exit

The sleep 1 is in there to reduce the race between the background job starting and the shell exiting. If you can avoid having to do everything in a single line you'll get better results separating the two sets of commands:

sudo bash /home/user/testsleep.sh from_end &
disown -h; exit
2
  • Many thanks for that, @StephenKitt, that seems to work great! Just a note: if I forget to do say sudo ls before I execute the command, so that my password is asked for and temporarily remembered, then I might get [1]+ Stopped sudo bash /home/user/testsleep.sh from_end ; logout ; There are stopped jobs., so I had to do fg until I saw and answered the password prompt. Btw, in syslog I get mypc user: Pre sleep: root...but mypc logger: Post sleep: root... - any idea why "pre sleep" has user and "post sleep" has logger as username?
    – sdaau
    Feb 5, 2015 at 14:00
  • 1
    The sudo prompt is normal if that execution needs a password. At least you get a chance to fix the problem ;-). As to logger appearing in the log instead of user, I can hazard a guess but I'd rather check. Feb 5, 2015 at 14:02

You must log in to answer this question.

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