8

I have two scripts - one to mount some folders over SSHFS - and one to unmount.

I would like to launch the mount script when my default Ubuntu desktop is launched (after I log in at the graphical console) - and the unmount script when I "Log Out..." from the cog-wheel at the top-right of the desktop.

Please can someone tell me how to achieve this? What are the most convenient/standard hooks to run commands on desktop launch / exit?

David Foerster
  • 36,264
  • 56
  • 94
  • 147
aSteve
  • 449
  • 3
  • 6
  • 19
  • I don't expect the timing to be critical. What matters is that the first script is executed within a second or so... before the user interactively launches applications. On logout, it just matters that the second script is executed before someone else logs in on console. – aSteve Aug 30 '14 at 20:45
  • I have root access. Installing packages is no problem. If possible, I'd like to use only user-level privileges - assuming there's a neat way to do that. My scripts do not need root. I'm looking for advise on how best to initiate my scripts on Unity start/stop... Most of my Linux/Unix experience is in a non-GUI context. With old-school XWindows and a vanilla window manager, I could have done this from .xinitrc. What is the best way with the modern, default, Unity desktop? – aSteve Aug 31 '14 at 14:04
  • I don't want to make the log-off action dependent upon what is/isn't mounted... That is all handled dynamically by the existing scripts. What I need is a neat way to execute the first script on log-on and the second on log-off for the GUI session on console. I've found "Startup Applications" - but that would only solve the first half of the problem. – aSteve Aug 31 '14 at 16:58
  • I don't think that "login applications" is the right strategy for either script. I have two scripts... one sets things up for my GUI session; the other cleans up after a GUI session. Both should be run as the same user as the GUI session. Neither requires any arguments. I need to find an appropriate way to launch the scripts - at the right times, that's all. No assumptions about what the scripts actually do should be necessary. This question is all about how to hook events coinciding with Unity log-on and log-off. – aSteve Aug 31 '14 at 17:27

3 Answers3

9

Considering your requirement of running a job when you login to Unity and not for other logins, an Upstart session job seems perfect.

You may have noticed it: processes that you run after a GUI login are under a second init process. This init is a proper Upstart init, and you can start and stop session jobs based on events emitted by it. No root privileges needed at all. Better yet (or worse depending on the perspective), this is not yet completely supported for headless systems. An SSH login didn't start the user init from a quick test that I made just now.

To create a session job, make a new .conf file in ~/.config/upstart. That's the default primary directory for Upstart session jobs ($XDG_CONFIG_HOME/upstart), create it if doesn't exist. Here's an example job:

tee ~/.config/upstart/myjob.conf <<EOF
description "My job"
start on desktop-start
stop on desktop-end

script 
       firefox 'http://upstart.ubuntu.com/cookbook/#session-job'
end script
EOF

You can manually control it:

start myjob 
# or
initctl start myjob

The service command are used to control system jobs (those in /etc/init.d or /etc/init). For controlling session jobs, one needs to use the initctl command, which is used to interact with Upstart.

See man upstart-events for more events you can use.

muru
  • 197,895
  • 55
  • 485
  • 740
  • I hadn't noticed... but... I agree - an upstart session job looks perfect. I'm probably missing something obvious... but having created ~/.config/upstart/myjob.conf (as above) when I execute "service myjob start" I get "myjob: unrecognized service" Any ideas? – aSteve Aug 31 '14 at 18:17
  • Solved it: I needed to use "start myjob" instead of "service myjob start". Another useful command was "initctl list" – aSteve Aug 31 '14 at 18:59
  • @aSteve sorry about that. I corrected it, – muru Sep 01 '14 at 06:22
  • No problem. The upstart/sessions approach definitely looks right. That said, I've not yet identified the best way to use it to execute separate (short lived) start and stop scripts. Can I use just 1 .conf file, or do I need 2? Should it be a "service" or a "task"? Should I use pre/post start and pre/post stop? I don't need/want a process to run between start and stop... unless, I guess, there's an easy way to put an icon in the toolbar... though that's, probably, overkill - for my purposes. – aSteve Sep 01 '14 at 10:31
  • @aSteve I'm not sure what you wish to do. If those separate scripts are independent, you can use one conf file and just add them all to the script block. It should be a task, I suppose. I suppose if you have a major long-lived session service running, you could use the pre-start/post-stop of that job. – muru Sep 01 '14 at 15:56
  • I want to run my up.sh script on "desktop-start" and my down.sh on "desktop-end" - each takes <1 seccond to complete. I don't need any process running as a service. If I add both up.sh and down.sh to a single script block, they are run in quick succession. With only pre/post start/stop blocks, "start myjob" blocks indefinitely. It isn't obvious how to associate tasks with events as I can only find samples that associate events with start and stop services. It feels the answer should be obvious - but it isn't to me, today, at least. – aSteve Sep 01 '14 at 17:45
  • @aSteve Tasks should have a similar configuration to services. Here, since the two scripts are reactions to different events, they should be in different .conf files, I think. – muru Sep 01 '14 at 17:54
  • Getting close... A task with "start on desktop-start" works perfectly on log-in. Unfortunately, a similar task with "start on desktop-end" is not triggered when I log out using the GUI. It does launch manually with "start myendtask". The desktop-end event is not triggered when I expect it to be.... perhaps not at all... and the man page is a little vague about when these signals/hooks should fire. – aSteve Sep 01 '14 at 20:59
  • 1
    Finally. After much hacking... I've discovered that I need the myendtask to be fired "on session-end", not "on desktop-end". This is somewhat counter-intuitive, but it works. (At last!) – aSteve Sep 01 '14 at 21:56
  • @aSteve that might have something to do with desktop-end being non-blocking and session-end being blocking (the latter waits for tasks to finish and the former doesn't), so the first is fine for stop on, but not for start on. – muru Sep 02 '14 at 04:19
  • I noticed that distinction... Asynchronous events alone (IMHO) don't explain why desktop-end tasks are not fired when I expect - but session-end tasks are. I'm impressed with upstart's capabilities - but I wish its documentation could be more transparent. :) – aSteve Sep 02 '14 at 09:36
1

The solution was to use upstart tasks. I required two tasks - one fired when the desktop initializes for a user; the second when the users session expires. The following two scripts work for me under Ubuntu 14.04.

In ~/.config/upstart/desktopOpen.conf

description "Desktop Open Task"
start on desktop-start
task
script
# Commands to mount sshfs go here as shell-script.
end script

In ~/.config/upstart/desktopClose.conf

description "Desktop Close Task"
start on session-end
task
script
# Commands to unmount sshfs go here as shell-script.
end script

My fingers are crossed that these events will continue to meet requirements in future Ubuntu releases. I thought it worth posting my solution here - in case it is of use to others.

aSteve
  • 449
  • 3
  • 6
  • 19
-1

Here are some suggestions for running a script after login:

StackOverflow Linux script after bootup: Cliff notes is to put your *.sh file in /etc/profile.d.

If you want to run scripts upon bootup, here are some suggestions for that:

StackOverflow Linux script after boot: Cliff notes is to use /etc/rc.local or crontab.

Higgs
  • 20
  • 1
    Neither of those options look 'right'. I only want to execute the script when I log-on/off in the sense of starting/ending a unity session. I don't want to run my scripts every time there is a new log-on. New log-ons may be remotely initiated over ssh etc - but I don't want these to execute the script as they do not initiate a new Unity session (on console). – aSteve Aug 29 '14 at 22:30