now uses 'script' to provide a scrollback buffer at reattaching. Otherwise all screen output while not attached gets lost

This commit is contained in:
Michael Krayer 2021-03-26 14:39:14 +01:00
parent 498481c491
commit 4d3636e77a
1 changed files with 78 additions and 23 deletions

101
session
View File

@ -8,8 +8,9 @@ typeset -A config
config=( config=(
[socket_dir]="/tmp/" [socket_dir]="/tmp/"
[socket_base]="session-$UID" [socket_base]="session-$UID"
[shell]="/bin/bash" [log_session]="yes"
[redraw]="winch" [scrollback]="50"
[detach_char]=""
) )
# Source from configuration file if available # Source from configuration file if available
if [ -f "$CONFIG_FILE" ]; then if [ -f "$CONFIG_FILE" ]; then
@ -23,18 +24,19 @@ if [ -f "$CONFIG_FILE" ]; then
done < $CONFIG_FILE done < $CONFIG_FILE
fi fi
## Set some variables # Set some variables
SOCKET_PREFIX="${config[socket_dir]}/${config[socket_base]}-" SOCKET_PREFIX="${config[socket_dir]}/${config[socket_base]}-"
SOCKET_SUFFIX=".socket" SOCKET_SUFFIX=".socket"
LOG_SUFFIX=".log"
# Exit codes # Exit codes
EXIT_SUCCESS=0 EXIT_SUCCESS=0
EXIT_INVALID_MODE=1 EXIT_INVALID_MODE=1
EXIT_SESSION_EXISTS=2 EXIT_INVALID_SUBMODE=2
EXIT_SESSION_NOT_EXIST=3 EXIT_SESSION_EXISTS=3
EXIT_ALREADY_IN_SESSION=4 EXIT_SESSION_NOT_EXIST=4
EXIT_INVALID_CONFIG=5 EXIT_ALREADY_IN_SESSION=5
EXIT_CONFIG_EXISTS=6 EXIT_CONFIG_NOT_GENERATED=6
EXIT_INVALID_CHOICE=7 EXIT_INVALID_CHOICE=7
## Functions ## Functions
@ -51,7 +53,7 @@ print_help() {
echo >&2 " help | | h display this help message" echo >&2 " help | | h display this help message"
echo >&2 "" echo >&2 ""
echo >&2 "$(basename $0) attach [name]" echo >&2 "$(basename $0) attach [name]"
echo >&2 " Attach to specified session. If no session name is provided, an interactive" echo >&2 " Attach to specified session. If no session name is provided, an interactive "
echo >&2 " selection menu is provided. Use <Ctrl-\\> to detach." echo >&2 " selection menu is provided. Use <Ctrl-\\> to detach."
echo >&2 "" echo >&2 ""
echo >&2 "$(basename $0) new [name]" echo >&2 "$(basename $0) new [name]"
@ -78,6 +80,9 @@ print_help() {
echo >&2 "" echo >&2 ""
echo >&2 "$(basename $0) is configured using the file '$CONFIG_FILE', which, if" echo >&2 "$(basename $0) is configured using the file '$CONFIG_FILE', which, if"
echo >&2 "non-existent, can be initialized with '$(basename $0) config generate'." echo >&2 "non-existent, can be initialized with '$(basename $0) config generate'."
echo >&2 "All sessions are logged by default in order to provide a scrollback"
echo >&2 "buffer at attaching. The logs are located in '${config[socket_dir]}'"
echo >&2 "and logs of terminated sessions may be cleared using '$(basename $0) log clear'."
} }
get_available_sessions() { get_available_sessions() {
@ -91,10 +96,25 @@ get_available_sessions() {
echo ${socket_names[@]} echo ${socket_names[@]}
} }
get_available_logs() {
local log_paths=(${SOCKET_PREFIX}*${LOG_SUFFIX})
local socket_names=()
for spath in ${log_paths[@]}; do
sname=${spath##${SOCKET_PREFIX}}
sname=${sname%%${LOG_SUFFIX}}
socket_names+=("${sname}")
done
echo ${socket_names[@]}
}
get_session_path() { get_session_path() {
echo "${SOCKET_PREFIX}${1}${SOCKET_SUFFIX}" echo "${SOCKET_PREFIX}${1}${SOCKET_SUFFIX}"
} }
get_log_path() {
echo "${SOCKET_PREFIX}${1}${LOG_SUFFIX}"
}
is_existing_session_path() { is_existing_session_path() {
if [ -S $1 ]; then if [ -S $1 ]; then
true true
@ -123,8 +143,8 @@ exit_if_in_session() {
} }
exit_if_existing_session() { exit_if_existing_session() {
if ! is_existing_session_name $session_name; then if is_existing_session_name $session_name; then
echo >&2 "Session '$session_name' does not exist." echo >&2 "Session '$session_name' already exists."
exit $EXIT_SESSION_NOT_EXIST exit $EXIT_SESSION_NOT_EXIST
fi fi
} }
@ -143,6 +163,13 @@ print_session_info() {
printf "%-24s %-20s %s\n" "$session_name" "$session_time" "$session_path" printf "%-24s %-20s %s\n" "$session_name" "$session_time" "$session_path"
} }
print_scrollback() {
local session_name=$1
local log_path=$(get_log_path $session_name)
printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' -
tail -n ${config[scrollback]} $log_path
}
## Parse first argument (= mode argument) ## Parse first argument (= mode argument)
if [[ "$#" -lt 1 ]]; then if [[ "$#" -lt 1 ]]; then
print_help print_help
@ -175,8 +202,12 @@ case $mode in
exit_if_nonexisting_session $session_name exit_if_nonexisting_session $session_name
fi fi
session_path=$(get_session_path $session_name) session_path=$(get_session_path $session_name)
CMD="dtach -a $session_path -r ${config[redraw]}" CMD="dtach -a $session_path -e ${config[detach_char]} -r winch "
exec $CMD #echo $CMD
echo "[attached to $session_name]"
[[ "${config[log_session]}" == "yes" ]] && print_scrollback $session_name
eval $CMD
exit $EXITSUCCESS
;; ;;
"new"|"n") "new"|"n")
exit_if_in_session exit_if_in_session
@ -191,9 +222,18 @@ case $mode in
fi fi
session_path=$(get_session_path $session_name) session_path=$(get_session_path $session_name)
CMD="env DTACH_SOCKET_PATH=$session_path DTACH_SESSION_NAME=$session_name " CMD="env DTACH_SOCKET_PATH=$session_path DTACH_SESSION_NAME=$session_name "
CMD+="dtach -c $session_path -r ${config[redraw]} ${config[shell]}" CMD+="dtach -c $session_path -e ${config[detach_char]} -r winch "
echo $CMD if [[ "${config[log_session]}" == "yes" ]]; then
exec $CMD log_path=$(get_log_path $session_name)
touch $log_path && chmod 600 $log_path
CMD+="/bin/script -q -f $log_path"
else
CMD+="/bin/bash"
fi
#echo $CMD
echo "[new session $session_name]"
eval $CMD
exit $EXITSUCCESS
;; ;;
"terminate"|"term"|"t"|"kill"|"k") "terminate"|"term"|"t"|"kill"|"k")
# Check if we are in terminate/kill mode # Check if we are in terminate/kill mode
@ -222,13 +262,15 @@ case $mode in
fi fi
for sname in ${session_name[@]}; do for sname in ${session_name[@]}; do
spath=$(get_session_path $sname) spath=$(get_session_path $sname)
logpath=$(get_log_path $sname)
PID=$(fuser $spath 2> /dev/null) PID=$(fuser $spath 2> /dev/null)
CMD="kill $SIGNAL $PID" if [ ! -z "$PID" ]; then
exec $CMD CMD="kill $SIGNAL $PID"
if [[ "$CLEANUP" -eq 1 ]]; then eval $CMD
CMD="rm $spath" else # this seems to be an orphan
exec $CMD CLEANUP=1
fi fi
[[ "$CLEANUP" -eq 1 ]] && rm $spath
done done
exit $EXIT_SUCCESS exit $EXIT_SUCCESS
;; ;;
@ -263,11 +305,11 @@ case $mode in
"config") "config")
if [[ "$1" != "generate" ]]; then if [[ "$1" != "generate" ]]; then
echo >&2 "Use '$(basename $0) config generate' to generate default configuration file." echo >&2 "Use '$(basename $0) config generate' to generate default configuration file."
exit $EXIT_INVALID_CONFIG exit $EXIT_INVALID_SUBMODE
fi fi
if [ -f "$CONFIG_FILE" ]; then if [ -f "$CONFIG_FILE" ]; then
echo >&2 "Configuration file '$CONFIG_FILE' already exists. Please remove it first." echo >&2 "Configuration file '$CONFIG_FILE' already exists. Please remove it first."
exit $EXIT_CONFIG_EXISTS exit $EXIT_CONFIG_NOT_GENERATED
fi fi
printf "" > $CONFIG_FILE printf "" > $CONFIG_FILE
for key in ${!config[@]}; do for key in ${!config[@]}; do
@ -275,6 +317,19 @@ case $mode in
done done
exit $EXIT_SUCCESS exit $EXIT_SUCCESS
;; ;;
"log")
if [[ "$1" != "clear" ]]; then
echo >&2 "Use '$(basename $0) log clear' to clear all unused log files."
exit $EXIT_INVALID_SUBMODE
fi
logs_avail=($(get_available_logs))
for sname in ${logs_avail[@]}; do
if ! is_existing_session_name $sname; then
rm $(get_log_path $sname)
fi
done
exit $EXIT_SUCCESS
;;
*) *)
echo >&2 "Invalid mode: ${mode}" echo >&2 "Invalid mode: ${mode}"
print_help print_help