now uses 'script' to provide a scrollback buffer at reattaching. Otherwise all screen output while not attached gets lost
This commit is contained in:
parent
498481c491
commit
4d3636e77a
101
session
101
session
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue