I have just restarted my Ubuntu, but I forgot that a virtual machine was open in the background (having a minimized icon on the taskbar). Is it possible to configure Ubuntu in a way that if a user-defined application is running, then issue a warning before restart/shutdown? I am using version 16.04.
1 Answers
Introduction
The script bellow monitors all or user-defined application for presence, and if that presence is found - the system will be prevented from shutting down via graphical dialog ( the shutdown via command line won't be affected , as this is task applied by system administrators who know what they're doing).
There are 3 options:
-a
Monitor any open applications.
-c
Graphically select an app
-s
specify .desktop file for app on command line
-h
prints the syntax and list of options.
The -c
option is appropriate for one session only, where you want to simply click on a window and monitor that. The -a
and -s
options are appropriate to be added as autostart entries to be launched on system login. -s
option can be used with either full path or a portion of it , e.g. either /usr/share/applications/firefox.desktop
or firefox.desktop
are equally acceptable.
Script Source
The script source is available here or on my GitHub. Users can obtain the script either via cloning the whole repository or using
wget https://raw.githubusercontent.com/SergKolo/sergrep/master/safe_shutdown.sh && chmod +x safe_shutdown.sh
command to obtain just the script itself.
#!/usr/bin/env bash
#
###########################################################
# Author: Serg Kolo , contact: 1047481448@qq.com
# Date: May 14th , 2016
# Purpose: Ensure that user closes all or specific
# running windows and exits without any work
# lost
# Written for: http://askubuntu.com/q/771227/295286
# Tested on: Ubuntu 14.04 LTS
###########################################################
# Copyright: Serg Kolo , 2016
#
# Permission to use, copy, modify, and distribute this software is hereby granted
# without fee, provided that the copyright notice above and this permission statement
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
ARGV0="$0"
ARGC=$#
_notify_user()
{
# Close the shutdown dialog and display
# graphical popup which will ask user's shutdown
# confirmation. If user clicks OK , we shutdown.
# If cancel - no action.
qdbus com.canonical.Unity \
/com/canonical/Unity/Session \
com.canonical.Unity.Session.CancelAction
if zenity --question --title='WARNING!' \
--text="You have running apps. Shutdown anyway ?" \
2> /dev/null
then
qdbus com.canonical.Unity \
/com/canonical/Unity/Session \
com.canonical.Unity.Session.Shutdown
fi
}
_get_running_apps()
{
# Gets list of .desktop files for each
# running app
qdbus org.ayatana.bamf \
/org/ayatana/bamf/matcher \
org.ayatana.bamf.matcher.RunningApplicationsDesktopFiles
}
_check_any_running()
{
# Among the running apps there's always one
# .desktop file, which is compiz.desktop.
# We want to know if there's anything besides that
if [ $( _get_running_apps | wc -l ) -gt 1 ];
then
_notify_user
fi
}
_check_specific_running()
{
# Get list of running apps and see if
# the .desktop file we got is on the list
if _get_running_apps | grep -q "$1"
then
_notify_user
fi
}
_select_app()
{
# xwininfo provides nice interface which allows selecting
# a window. The rest is just simple parsing and passing
# around the XID of the app.
notify-send 'Select a window you would like to monitor '
XID=$(xwininfo -int | awk '/xwininfo: Window id/{print $4}')
APP=$(qdbus org.ayatana.bamf \
/org/ayatana/bamf/matcher \
org.ayatana.bamf.matcher.ApplicationForXid $XID )
qdbus org.ayatana.bamf \
"$APP" org.ayatana.bamf.application.DesktopFile
}
_print_usage()
{
cat <<EOF
safe_shutdown.sh [-a | -c |-s DESKTOP_FILE | -h ]
Options:
-a Monitor any open applications.
-c Graphically select an app
-s specify .desktop file for app on command line
-h print this text
Copyright Serg Kolo , 2016
EOF
}
parse_args()
{
if [ $ARGC -eq 0 ] ; then
printf "%s: No option specified\n Usage:\n" ${ARGV0##*/}
_print_usage
exit 1
fi
local OPTIND opt
while getopts "acs:" opt
do
case ${opt} in
a) FUNCTION="_check_any_running"
break
;;
c)
DESK_FILE=$(_select_app )
FUNCTION=" _check_specific_running $DESK_FILE "
break
;;
s) DESK_FILE=${OPTARG}
FUNCTION=" _check_specific_running $DESK_FILE "
break
;;
h) _print_usage
exit 0
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 1
;;
esac
done
shift $((OPTIND-1))
}
main()
{
# Basic idea is to let user chose what to do
# then monitor dbus for appropriate signal
# Once the RebootRequested signal is received
# then perform appropriate checks ( for a specific
# or all apps ).
local FUNCTION
parse_args "$@"
dbus-monitor --profile \
"interface='com.canonical.Unity.Session',type=signal" |
while read -r line;
do
case "$line" in
*RebootRequested*) $FUNCTION ;;
esac
done
}
main "$@"

- 105,154
- 20
- 279
- 497
-
1I continuously get surprised how much one can do with a few lines of code. Obviously, it will take some time to fully go through this stuff, which is highly appreciated. – Matsmath May 14 '16 at 17:25
-
@Matsmath Always glad to assist.Let me know if you need any other features added to this script – Sergiy Kolodyazhnyy May 14 '16 at 17:30
top
running), as long as it is manually started from a terminal. I created a .desktop file just like this (with the obvious modifications), and it indeed shows up in the Startup applications app. However, it does not seem to be working. – Matsmath May 12 '16 at 12:50~/.config/autostart
folder. I'll post an answer later today when i have time. – Sergiy Kolodyazhnyy May 12 '16 at 18:39