-
-
Save caktux/c9fd567b396f6fdc0468 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# | |
# upstream: git://gist.github.com/1019125.git | |
VERBOSITY=0 | |
LOCK="" | |
CR=" | |
" | |
error() { echo "$@" 1>&2; } | |
fail() { [ $# -eq 0 ] || error "$@"; exit 1; } | |
Usage() { | |
cat <<EOF | |
Usage: ${0##*/} [ options ] sess_name command | |
interact with gnu screen | |
${0##*/} provides a possibly simpler interface to interacting with screen. | |
options: | |
-c|--create create the session, fail if it exists | |
-X|--command pass command through to screen (-X) | |
-k|--keep-open keep the new window open after running command | |
-K|--keep-open-timeout TIME | |
keep window open for 'TIME' seconds after command | |
finishes | |
-t|--title TITLE create new window with title 'TITLE' | |
-v|--verbose increase verbosity | |
-p|--window WINDOW run in existing window 'WINDOW' | |
-q|--quit quit the session, closing all windows | |
fail if it does not exist | |
-R|--new-if-needed create a new session if 'sess_name' does not exist | |
-s|--stuff use "stuff" to execute command rather than 'screen' | |
requires --window. | |
-x|--kill kill a window (requires --window) | |
Example: | |
- create a new screen session (failing if it exists) | |
$ ${0##*/} mysession --create | |
- run a command via 'exec' in window 0 | |
$ ${0##*/} mysession --window 0 ls | |
- create a new window and run a shell there with title 'newwin' | |
shell will close when exited | |
$ ${0##*/} mysession --title newwin /bin/bash | |
- stuff a string into 'newwin' (hopefully at at shell prompt) | |
$ ${0##*/} mysession --title echo hi world | |
- forcefully kill the window 'newwin' | |
$ ${0##*/} mysession --window newwin --kill | |
- clean up, killing all processes and windows | |
$ ${0##*/} mysession --quit | |
EOF | |
} | |
bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || error "$@"; exit 1; } | |
getlock() { | |
command -v lockfile-create >/dev/null || return 0 | |
LOCK="$HOME/.${0##*/}.${session}" && | |
lockfile-create --use-pid "$LOCK" && | |
trap cleanlock EXIT || | |
fail "failed to create lock" | |
} | |
cleanlock() { | |
[ -n "$LOCK" ] || return 0; | |
lockfile-remove "$LOCK" || | |
{ error "WARN: removing lock failed: $LOCK"; LOCK=""; return 1; } | |
LOCK=""; | |
} | |
short_opts="chkKp:qSst:Xx" | |
long_opts="command,create,help,quit,keep-open,keep-open-timeout:,kill,new-if-needed,stuff,title:,window:,verbose" | |
getopt_out=$(getopt --name "${0##*/}" \ | |
--options "${short_opts}" --long "${long_opts}" -- "$@") && | |
eval set -- "${getopt_out}" || | |
bad_Usage | |
window="" | |
title="" | |
keep_open=false | |
ko_timeout="" | |
new_if_needed=false | |
lockfile="" | |
stuff=false | |
create=false | |
command=false | |
quit=false | |
kill=false | |
noargs_needed=false | |
rS="-r" # '-r' or '-S'. if creating a new session will be -S | |
while [ $# -ne 0 ]; do | |
cur=${1}; next=${2}; | |
case "$cur" in | |
-X|--command) command=true;; | |
-c|--create) create=true; noargs_needed=true;; | |
-h|--help) Usage ; exit 0;; | |
-k|--keep-open) keep_open=true;; | |
-K|--keep-open-timeout) keep_open=true; ko_timeout=${2}; shift;; | |
-q|--quit) quit=true; noargs_needed=true;; | |
-R|--new-if-needed) new_if_needed=true;; | |
-s|--stuff) stuff=true;; | |
-t|--title) title=${2}; shift;; | |
-v|--verbose) VERBOSITY=$((${VERBOSITY}+1));; | |
-x|--kill) kill=true; noargs_needed=true;; | |
-p|--window) window=${2}; shift;; | |
--) shift; break;; | |
esac | |
shift; | |
done | |
[ $# -gt 0 ] || bad_Usage "must provide session" | |
session="${1}" | |
shift; | |
{ [ $# -gt 0 ] || $noargs_needed; } || | |
bad_Usage "must provide screen session name and command" | |
[ -n "$window" ] && { "$keep_open" || [ -n "$title" ]; } && | |
bad_Usage "--title and --keep-open are incompatible with --window" | |
$quit && [ $# -ne 0 ] && | |
bad_Usage "args other than session name were given to quit" | |
if $kill; then | |
$create && fail "create and kill are incompatible" | |
$quit && fail "kill and quit are incompatible" | |
[ -n "$window" ] || fail "kill must have --window" | |
[ $# -eq 0 ] || fail "kill takes no arguments"; | |
fi | |
if $quit; then | |
$create && fail "create and quit are incompatible" | |
[ $# -eq 0 ] || fail "quit takes no arguments"; | |
fi | |
# get a lock to avoid a race between looking for session and creating it | |
getlock || fail "failed to get lock" | |
found=$(screen -ls | awk '-F\t' '$2 ~ m {print $2}' "m=[0-9]+[.]$session") | |
if [ -z "$found" ] && $quit; then | |
fail "failed to quit $session. not found" | |
elif [ -z "$found" ]; then | |
{ $create || $new_if_needed; } || | |
fail "no session '$session' found. perhaps you want --new-if-needed" | |
rS="-S" | |
if [ -n "$window" ]; then | |
# if 'create' and 'window', create the window here, and execute in it below | |
screen -d -m -S "$session" -t "${window}" | |
rS="-r" | |
elif [ $# -eq 0 ]; then | |
screen -d -m -S "$session" ${title:+-t "${title}"} | |
exit | |
fi | |
elif $quit; then | |
screen -r "$session" -x -X quit || fail "failed to quit $session [$found]" | |
exit | |
elif $create; then | |
fail "create specified, but '$session' existed at '$found'" | |
fi | |
$create && [ $# -eq 0 ] && exit 0 | |
if [ -n "$window" ]; then | |
if $stuff; then | |
screen $rS "$session" -x -p "$window" -X stuff "$*${CR}" | |
elif $kill; then | |
screen $rS "$session" -x -p "$window" -X kill | |
else | |
$command && cmd="" || cmd="exec" | |
screen $rS "$session" -x -p "$window" -X $cmd "$@" | |
fi | |
elif $keep_open; then | |
sh="sh"; read="read x" | |
[ -n "${ko_timeout}" ] && | |
sh="bash" && read="read -t ${ko_timeout} x" | |
exec screen $rS "$session" -x -X screen ${title:+-t "${title}"} \ | |
$sh -c '"$@"; echo Hit Enter to close; '"$read" inscreen-keepopen "$@" | |
else | |
cmd="screen" | |
$command && cmd="" | |
exec screen $rS "$session" -x -X $cmd ${title:+-t "${title}"} "$@" | |
fi | |
cleanlock || fail "failed to remove lock" | |
# vi: ts=4 noexpandtab |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment