Skip to content

Instantly share code, notes, and snippets.

@thisdavej
Last active February 8, 2022 15:31
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save thisdavej/582fde9133baa1123f49c32d2955a4f6 to your computer and use it in GitHub Desktop.
Save thisdavej/582fde9133baa1123f49c32d2955a4f6 to your computer and use it in GitHub Desktop.
Displays a user friendly menu if remote host name is included in a file. See http://thisdavej.com/controlling-a-raspberry-pi-from-a-mobile-device-with-bonus-menu-too/ for more information.
show_menu () {
# We show the host name right in the menu title so we know which Pi we are connected to
OPTION=$(whiptail --title "Menu (Host:$(hostname))" --menu "Choose your option:" 12 36 5 \
"1" "Current time" \
"2" "Calendar" \
"3" "Uptime" \
"4" "Reboot Pi" \
"5" "Shut down Pi" 3>&1 1>&2 2>&3)
BUTTON=$?
# Exit if user pressed cancel or escape
if [[ ($BUTTON -eq 1) || ($BUTTON -eq 255) ]]; then
exit 1
fi
if [ $BUTTON -eq 0 ]; then
case $OPTION in
1)
MSG="$(date)"
whiptail --title "Current time" --msgbox "$MSG" 8 36
show_menu
;;
2)
# We use "ncal -h" to turn off highlighting of today's date since
# highlighting produces non-printable chars that don't look good.
whiptail --title "Calendar" --textbox /dev/stdin 13 26 <<<"$(ncal -bh)"
show_menu
;;
3)
MSG="$(uptime)"
whiptail --title "Uptime info" --msgbox "$MSG" 8 36
show_menu
;;
4)
# For sensitive commands, we make sure they must press extra keys
confirmAnswer "Are you sure you want to reboot the Pi?"
if [ $? = 0 ]; then
echo Rebooting...
sudo reboot
else
show_menu
fi
;;
5)
confirmAnswer "Are you sure you want to shut down the Pi?"
if [ $? = 0 ]; then
echo Shutting down...
sudo poweroff
else
show_menu
fi
;;
esac
fi
}
#!/bin/bash
## USAGE
## rmenu [options]
##
## DESCRIPTION
## rmenu (remote menu) displays a user-friendly menu. A typical use case is to
## display the menu when certain remote hosts connect using SSH. The menu is
## displayed if the host MAC address is included in an rmenu_hosts file (contained
## in the same directory as the rmenu script). The rmenu command is typically
## added to the user .profile (rmenu -c) so it will be invoked when a user
## connects remotely through SSH. To always show the menu no matter what
## remote host connects, simply invoke rmenu without any parameters.
##
## This script was originally created to enable a menu to appear when
## connecting to a Raspberry Pi from an SSH client running on a mobile device.
## Feel free to use this script and tweak the menu and make it useful for your
## context!
##
## OPTIONS
## -c, --conditional Show menu if remote host is in the rmenu_hosts file.
## The rmenu_hosts file needs to be in the same directory
## as the rmenu script. If remote host is not coming
## through SSH, menu will not be shown either.
## -m , --menu_num The menu number to invoke. By default, the menu code in
## menu1.sh to display the menu. You can create additional
## files in the same directory as rmenu such as menu2.sh
## to invoke different menus.
##
## -h, --help Display this message.
##
## Example rmenu_hosts file (lines starting with "#" are ignored)
## # MAC addresses of hosts that should see remote menu when make SSH connection
## de:57:33:a4:8a:2b
##
## DEPENDENCIES
## whiptail
##
## IMPLEMENTATION
## Author: Dave Johnson (https://thisdavej.com/)
## Copyright: Copyright (c) https://thisdavej.com/
## License: MIT License (MIT)
##
confirmAnswer () {
whiptail --title "Confirmation" --yes-button "Yes" --no-button "No" --defaultno --yesno "$1" 8 36
return $?
# returns 0 = yes, 1 = no, 255 = escape key hit
}
# Modify the menu and commands below to suit your needs. On my Android device, five menu items is a good
# number to avoid vertical scrolling.
show_menu_if_host_in_list () {
# If we are not coming through SSH (we are in through VNC, etc.), $SSH_CONNECTION will not be set.
# Don't show the menu in this case if someone invokes directly from the terminal. Most of the time,
# the rmenu command will be invoked through .profile and .profile is not used when launching terminal
# sessions from the desktop, only when connecting through an SSH connection.
if [ -z "$SSH_CONNECTION" ]; then
clear
show_menu
exit
fi
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
menuhosts_file=$DIR/rmenu_hosts
if [ ! -f "$menuhosts_file" ]; then
echo "$menuhosts_file" file not found. Cannot evaluate whether remote host is in the list.
exit 1
fi
declare -a MENU_HOSTS
MENU_HOSTS=( `cat "$menuhosts_file"`)
SSH_CLIENT_IP=$(echo $SSH_CONNECTION | awk '{ print $1 }')
SSH_CLIENT_MAC_ADDRESS=$(arp -an $SSH_CLIENT_IP | awk '{ print $4 }')
# Make upper case for string comparison
SSH_CLIENT_MAC_ADDRESS=${SSH_CLIENT_MAC_ADDRESS^^}
FOUND_MATCH=false
for i in "${MENU_HOSTS[@]}"
do
if [[ "$i" == "#"* ]]; then
continue
fi
if [ "$SSH_CLIENT_MAC_ADDRESS" == "${i^^}" ]; then
FOUND_MATCH=true
break
fi
done
if $FOUND_MATCH; then
clear
show_menu
fi
}
usage() {
[ "$*" ] && echo "$0: $*"
sed -n '/^##/,/^$/s/^## \{0,1\}//p' "$0"
exit 2
} 2>/dev/null
MENU_NUMBER=1
while [[ $# -gt 0 ]]
do
key="$1"
case $key in
-c|--conditional)
CONDITIONAL=true
;;
-m|--menu_num)
MENU_NUMBER="$2"
shift
;;
-h|--help)
usage
;;
*)
# unknown option
;;
esac
shift # past argument or value
done
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source $DIR/menu$MENU_NUMBER.sh
if [ "$CONDITIONAL" = true ] ; then
show_menu_if_host_in_list
else
show_menu
fi
# MAC addresses of hosts that should see remote menu when make SSH connection
ac:37:43:a6:8a:9f
#7c:df:44:ed:57:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment