mirror of
https://github.com/GameServerManagers/LinuxGSM
synced 2026-08-18 20:23:04 -04:00
When connected to a server via ssh, and the server doesn't have the
proper terminfo, tmux will fail with 'unsupported terminal' errors.
These errors are not surfaced by the scripts, e.g. details, start,
stop, so they result in either silent failures or don't work at all.
e.g. `./mcserver details` on my server showed 0% CPU, 0% Memory,
and STOPPED for the server status when the server was
actually running. This was because the tmux calls to get
this info failed.
The root cause of this was that I was connected to my server
via kitty, a terminal emulator that my server did not have
terminfo for.
This can be resolved via running `infocmp -x xterm-kitty | ssh
YOUR-SERVER -- tic -x -` and replacing `xterm-kitty` with whatever
is appropriate, or by setting TERM=xterm-256color in the ssh config,
but that is not obvious to do when presented with silent failures.
This commit sets TERM=screen for all non-interactive tmux calls,
which resolves the issue. Note that the `console` command does not
set this, as that is an interactive shell, and the user's terminfo
should be passed.
Co-authored-by: Daniel Gibbs <me@danielgibbs.co.uk>
209 lines
6.7 KiB
Bash
Executable file
209 lines
6.7 KiB
Bash
Executable file
#!/bin/bash
|
|
# LinuxGSM command_start.sh module
|
|
# Author: Daniel Gibbs
|
|
# Contributors: https://linuxgsm.com/contrib
|
|
# Website: https://linuxgsm.com
|
|
# Description: Starts the server.
|
|
|
|
commandname="START"
|
|
commandaction="Starting"
|
|
moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
|
|
addtimestamp="gawk '{ print strftime(\\\"[$logtimestampformat]\\\"), \\\$0 }'"
|
|
fn_firstcommand_set
|
|
|
|
# This will allow the Jedi Knight 2 version to be printed in console on start.
|
|
# Used to allow update to detect JK2MV server version.
|
|
fn_start_jk2() {
|
|
fn_start_tmux
|
|
TERM=screen tmux -L "${socketname}" end -t "${sessionname}" version ENTER > /dev/null 2>&1
|
|
}
|
|
|
|
fn_start_tmux() {
|
|
# check for tmux size variables.
|
|
if [[ "${servercfgtmuxwidth}" =~ ^[0-9]+$ ]]; then
|
|
sessionwidth="${servercfgtmuxwidth}"
|
|
else
|
|
sessionwidth="80"
|
|
fi
|
|
if [[ "${servercfgtmuxheight}" =~ ^[0-9]+$ ]]; then
|
|
sessionheight="${servercfgtmuxheight}"
|
|
else
|
|
sessionheight="23"
|
|
fi
|
|
|
|
# Log rotation.
|
|
fn_script_log_info "Rotating log files"
|
|
if [ "${engine}" == "unreal2" ] && [ -f "${gamelog}" ]; then
|
|
mv "${gamelog}" "${gamelogdate}"
|
|
fi
|
|
if [ -f "${lgsmlog}" ]; then
|
|
mv "${lgsmlog}" "${lgsmlogdate}"
|
|
fi
|
|
if [ -f "${consolelog}" ]; then
|
|
mv "${consolelog}" "${consolelogdate}"
|
|
fi
|
|
|
|
# Create a starting lockfile that only exists while the start command is running.
|
|
date '+%s' > "${lockdir:?}/${selfname}-starting.lock"
|
|
|
|
fn_reload_startparameters
|
|
|
|
# Create uid to ensure unique tmux socket name.
|
|
if [ ! -f "${datadir}/${selfname}.uid" ]; then
|
|
check_status.sh
|
|
if [ "${status}" != "0" ]; then
|
|
# stop running server (if running) to prevent lingering tmux sessions.
|
|
exitbypass=1
|
|
command_stop.sh
|
|
fi
|
|
uid=$(date '+%s' | sha1sum | head -c 8)
|
|
echo "${uid}" > "${datadir}/${selfname}.uid"
|
|
socketname="${sessionname}-$(cat "${datadir}/${selfname}.uid")"
|
|
fi
|
|
|
|
if [ "${shortname}" == "av" ]; then
|
|
cd "${systemdir}" || exit
|
|
else
|
|
cd "${executabledir}" || exit
|
|
fi
|
|
|
|
TERM=screen tmux -L "${socketname}" new-session -d -x "${sessionwidth}" -y "${sessionheight}" -s "${sessionname}" "${preexecutable} ${executable} ${startparameters}" 2> "${lgsmlogdir}/.${selfname}-tmux-error.tmp"
|
|
|
|
# Create logfile.
|
|
touch "${consolelog}"
|
|
|
|
# tmux compiled from source will return "master", therefore ignore it.
|
|
if [ "${tmuxversion}" == "master" ]; then
|
|
fn_script_log "tmux version: master (user compiled)"
|
|
echo -e "tmux version: master (user compiled)" >> "${consolelog}"
|
|
fi
|
|
|
|
# Enable console logging.
|
|
if [ "${consolelogging}" == "on" ] || [ -z "${consolelogging}" ]; then
|
|
# timestamp will break mcb update check.
|
|
if [ "${logtimestamp}" == "on" ] && [ "${shortname}" != "mcb" ]; then
|
|
TERM=screen tmux -L "${socketname}" pipe-pane -o -t "${sessionname}" "exec bash -c \"cat | $addtimestamp\" >> '${consolelog}'"
|
|
else
|
|
TERM=screen tmux -L "${socketname}" pipe-pane -o -t "${sessionname}" "exec cat >> '${consolelog}'"
|
|
fi
|
|
else
|
|
echo -e "Console logging disabled in settings" >> "${consolelog}"
|
|
fn_script_log_info "Console logging disabled in settings"
|
|
fi
|
|
|
|
fn_sleep_time_1
|
|
|
|
# If the server fails to start.
|
|
check_status.sh
|
|
if [ "${status}" == "0" ]; then
|
|
fn_print_fail_nl "Unable to start ${servername}"
|
|
fn_script_log_fail "Unable to start ${servername}"
|
|
if [ -s "${lgsmlogdir}/.${selfname}-tmux-error.tmp" ]; then
|
|
fn_print_fail_nl "Unable to start ${servername}: tmux error:"
|
|
fn_script_log_fail "Unable to start ${servername}: tmux error"
|
|
echo -e ""
|
|
echo -e "Command"
|
|
fn_messages_separator
|
|
echo -e "tmux -L \"${sessionname}\" new-session -d -s \"${sessionname}\" \"${preexecutable} ${executable} ${startparameters}\"" | tee -a "${lgsmlog}"
|
|
echo -e ""
|
|
echo -e "Error"
|
|
fn_messages_separator
|
|
tee -a "${lgsmlog}" < "${lgsmlogdir}/.${selfname}-tmux-error.tmp"
|
|
|
|
# Detected error https://linuxgsm.com/support
|
|
if grep -c "Operation not permitted" "${lgsmlogdir}/.${selfname}-tmux-error.tmp"; then
|
|
echo -e ""
|
|
echo -e "Fix"
|
|
fn_messages_separator
|
|
if ! grep "tty:" /etc/group | grep "$(whoami)"; then
|
|
echo -e "$(whoami) is not part of the tty group."
|
|
fn_script_log_info "$(whoami) is not part of the tty group."
|
|
group=$(grep tty /etc/group)
|
|
echo -e ""
|
|
echo -e " ${group}"
|
|
fn_script_log_info "${group}"
|
|
echo -e ""
|
|
echo -e "Run the following command with root privileges."
|
|
echo -e ""
|
|
echo -e " usermod -G tty $(whoami)"
|
|
echo -e ""
|
|
echo -e "${italic}https://linuxgsm.com/tmux-op-perm"
|
|
fn_script_log_info "https://linuxgsm.com/tmux-op-perm"
|
|
else
|
|
echo -e "No known fix currently. Please log an issue."
|
|
fn_script_log_info "No known fix currently. Please log an issue."
|
|
echo -e "${italic}https://linuxgsm.com/support"
|
|
fn_script_log_info "https://linuxgsm.com/support"
|
|
fi
|
|
fi
|
|
fi
|
|
# Remove starting lockfile when command ends.
|
|
rm -f "${lockdir:?}/${selfname}-starting.lock"
|
|
core_exit.sh
|
|
else
|
|
# Create start lockfile that exists only when the server is running.
|
|
date '+%s' > "${lockdir:?}/${selfname}-started.lock"
|
|
echo "${version}" >> "${lockdir}/${selfname}-started.lock"
|
|
echo "${port}" >> "${lockdir}/${selfname}-started.lock"
|
|
fn_print_ok "${servername}"
|
|
fn_script_log_pass "Started ${servername}"
|
|
|
|
# Create last started Lockfile.
|
|
date +%s > "${lockdir}/${selfname}-last-started.lock"
|
|
|
|
fn_print_ok "${servername}"
|
|
fn_script_log_pass "Started ${servername}"
|
|
if [ "${statusalert}" == "on" ] && [ "${firstcommandname}" == "START" ]; then
|
|
alert="started"
|
|
alert.sh
|
|
elif [ "${statusalert}" == "on" ] && [ "${firstcommandname}" == "RESTART" ]; then
|
|
alert="restarted"
|
|
alert.sh
|
|
fi
|
|
fi
|
|
rm -f "${lgsmlogdir:?}/.${selfname}-tmux-error.tmp" 2> /dev/null
|
|
echo -en "\n"
|
|
}
|
|
|
|
# If user ran the start command monitor will become enabled.
|
|
if [ "${firstcommandname}" == "START" ] || [ "${firstcommandname}" == "RESTART" ]; then
|
|
date '+%s' > "${lockdir:?}/${selfname}-monitoring.lock"
|
|
fi
|
|
|
|
fn_print_dots ""
|
|
check.sh
|
|
|
|
# If the server already started dont start again.
|
|
if [ "${status}" != "0" ]; then
|
|
fn_print_dots "${servername}"
|
|
fn_print_skip_nl "${servername} is already running"
|
|
fn_script_log_error "${servername} is already running"
|
|
if [ -z "${exitbypass}" ]; then
|
|
# Remove starting lockfile when command ends.
|
|
rm -f "${lockdir:?}/${selfname}-starting.lock"
|
|
core_exit.sh
|
|
fi
|
|
fi
|
|
|
|
fix.sh
|
|
info_game.sh
|
|
core_logs.sh
|
|
|
|
# Will check for updates if updateonstart is yes.
|
|
if [ "${updateonstart}" == "yes" ] || [ "${updateonstart}" == "1" ] || [ "${updateonstart}" == "on" ]; then
|
|
exitbypass=1
|
|
unset updateonstart
|
|
command_update.sh
|
|
fn_firstcommand_reset
|
|
fi
|
|
|
|
fn_print_dots "${servername}"
|
|
if [ "${shortname}" == "jk2" ]; then
|
|
fn_start_jk2
|
|
else
|
|
fn_start_tmux
|
|
fi
|
|
|
|
# Remove starting lockfile when command ends.
|
|
rm -f "${lockdir:?}/${selfname}-starting.lock"
|
|
core_exit.sh
|