From 51ad60e1805f0432274a850a8ac602b844f308a9 Mon Sep 17 00:00:00 2001 From: "Silas J. Matson" Date: Sun, 19 Jul 2026 11:45:40 -0700 Subject: [PATCH] fix: Set TERM=screen for all non-interactive tmux calls (#4860) 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 --- lgsm/modules/check_status.sh | 2 +- lgsm/modules/command_send.sh | 2 +- lgsm/modules/command_start.sh | 8 ++++---- lgsm/modules/command_stop.sh | 12 ++++++------ lgsm/modules/info_distro.sh | 2 +- lgsm/modules/update_xnt.sh | 4 ++-- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/lgsm/modules/check_status.sh b/lgsm/modules/check_status.sh index e017b89ec..98d2a3772 100755 --- a/lgsm/modules/check_status.sh +++ b/lgsm/modules/check_status.sh @@ -7,4 +7,4 @@ moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" -status=$(tmux -L "${socketname}" list-sessions -F "#{session_name}" 2> /dev/null | grep -Ecx "^${sessionname}") +status=$(TERM=screen tmux -L "${socketname}" list-sessions -F "#{session_name}" 2> /dev/null | grep -Ecx "^${sessionname}") diff --git a/lgsm/modules/command_send.sh b/lgsm/modules/command_send.sh index 20ef188e3..8b8a1a252 100755 --- a/lgsm/modules/command_send.sh +++ b/lgsm/modules/command_send.sh @@ -27,7 +27,7 @@ if [ "${status}" != "0" ]; then echo "" fn_print_dots "Sending command to console: \"${commandtosend}\"" fn_print_ok_nl "Sending command to console: \"${commandtosend}\"" - tmux -L "${socketname}" send-keys -t "${sessionname}" "${commandtosend}" ENTER + TERM=screen tmux -L "${socketname}" send-keys -t "${sessionname}" "${commandtosend}" ENTER fn_script_log_pass "Command \"${commandtosend}\" sent to console" else fn_print_error_nl "Unable to send command to console. Server not running" diff --git a/lgsm/modules/command_start.sh b/lgsm/modules/command_start.sh index a4e07b44b..43b7a3858 100755 --- a/lgsm/modules/command_start.sh +++ b/lgsm/modules/command_start.sh @@ -15,7 +15,7 @@ fn_firstcommand_set # Used to allow update to detect JK2MV server version. fn_start_jk2() { fn_start_tmux - tmux -L "${socketname}" end -t "${sessionname}" version ENTER > /dev/null 2>&1 + TERM=screen tmux -L "${socketname}" end -t "${sessionname}" version ENTER > /dev/null 2>&1 } fn_start_tmux() { @@ -67,7 +67,7 @@ fn_start_tmux() { cd "${executabledir}" || exit fi - tmux -L "${socketname}" new-session -d -x "${sessionwidth}" -y "${sessionheight}" -s "${sessionname}" "${preexecutable} ${executable} ${startparameters}" 2> "${lgsmlogdir}/.${selfname}-tmux-error.tmp" + 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}" @@ -82,9 +82,9 @@ fn_start_tmux() { if [ "${consolelogging}" == "on" ] || [ -z "${consolelogging}" ]; then # timestamp will break mcb update check. if [ "${logtimestamp}" == "on" ] && [ "${shortname}" != "mcb" ]; then - tmux -L "${socketname}" pipe-pane -o -t "${sessionname}" "exec bash -c \"cat | $addtimestamp\" >> '${consolelog}'" + TERM=screen tmux -L "${socketname}" pipe-pane -o -t "${sessionname}" "exec bash -c \"cat | $addtimestamp\" >> '${consolelog}'" else - tmux -L "${socketname}" pipe-pane -o -t "${sessionname}" "exec cat >> '${consolelog}'" + TERM=screen tmux -L "${socketname}" pipe-pane -o -t "${sessionname}" "exec cat >> '${consolelog}'" fi else echo -e "Console logging disabled in settings" >> "${consolelog}" diff --git a/lgsm/modules/command_stop.sh b/lgsm/modules/command_stop.sh index ab827314d..056214456 100755 --- a/lgsm/modules/command_stop.sh +++ b/lgsm/modules/command_stop.sh @@ -15,7 +15,7 @@ fn_stop_graceful_ctrlc() { fn_print_dots "Graceful: CTRL+c" fn_script_log_info "Graceful: CTRL+c" # Sends CTRL+c. - tmux -L "${socketname}" send-keys -t "${sessionname}" C-c > /dev/null 2>&1 + TERM=screen tmux -L "${socketname}" send-keys -t "${sessionname}" C-c > /dev/null 2>&1 # Waits up to 30 seconds giving the server time to shutdown gracefully. for seconds in {1..30}; do check_status.sh @@ -47,7 +47,7 @@ fn_stop_graceful_cmd() { fn_print_dots "Graceful: sending \"${1}\"" fn_script_log_info "Graceful: sending \"${1}\"" # Sends specific stop command. - tmux -L "${socketname}" send -t "${sessionname}" ENTER "${1}" ENTER > /dev/null 2>&1 + TERM=screen tmux -L "${socketname}" send -t "${sessionname}" ENTER "${1}" ENTER > /dev/null 2>&1 # Waits up to ${seconds} seconds giving the server time to shutdown gracefully. for ((seconds = 1; seconds <= ${2}; seconds++)); do check_status.sh @@ -79,7 +79,7 @@ fn_stop_graceful_goldsrc() { fn_print_dots "Graceful: sending \"quit\"" fn_script_log_info "Graceful: sending \"quit\"" # sends quit - tmux -L "${socketname}" send -t "${sessionname}" quit ENTER > /dev/null 2>&1 + TERM=screen tmux -L "${socketname}" send -t "${sessionname}" quit ENTER > /dev/null 2>&1 # Waits 3 seconds as goldsrc servers restart with the quit command. for seconds in {1..3}; do fn_sleep_time_1 @@ -289,10 +289,10 @@ fn_stop_graceful_avorion() { fn_print_dots "Graceful: /save /stop" fn_script_log_info "Graceful: /save /stop" # Sends /save. - tmux -L "${socketname}" send-keys -t "${sessionname}" /save ENTER > /dev/null 2>&1 + TERM=screen tmux -L "${socketname}" send-keys -t "${sessionname}" /save ENTER > /dev/null 2>&1 fn_sleep_time_5 # Sends /quit. - tmux -L "${socketname}" send-keys -t "${sessionname}" /stop ENTER > /dev/null 2>&1 + TERM=screen tmux -L "${socketname}" send-keys -t "${sessionname}" /stop ENTER > /dev/null 2>&1 # Waits up to 30 seconds giving the server time to shutdown gracefully. for seconds in {1..30}; do check_status.sh @@ -351,7 +351,7 @@ fn_stop_tmux() { fn_print_dots "${servername}" fn_script_log_info "tmux kill-session: ${sessionname}: ${servername}" # Kill tmux session. - tmux -L "${socketname}" kill-session -t "${sessionname}" > /dev/null 2>&1 + TERM=screen tmux -L "${socketname}" kill-session -t "${sessionname}" > /dev/null 2>&1 fn_sleep_time_1 check_status.sh if [ "${status}" == "0" ]; then diff --git a/lgsm/modules/info_distro.sh b/lgsm/modules/info_distro.sh index 1d74ac635..4ece95e4d 100755 --- a/lgsm/modules/info_distro.sh +++ b/lgsm/modules/info_distro.sh @@ -11,7 +11,7 @@ moduleselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")" ### Game Server pid if [ "${status}" == "1" ]; then - gameserverpid="$(tmux -L "${socketname}" list-sessions -F "#{session_name} #{pane_pid}" | grep "^${sessionname} " | awk '{print $NF}')" + gameserverpid="$(TERM=screen tmux -L "${socketname}" list-sessions -F "#{session_name} #{pane_pid}" | grep "^${sessionname} " | awk '{print $NF}')" if [ "${engine}" == "source" ]; then srcdslinuxpid="$(pgrep -P "${gameserverpid}" -x srcds_linux 2> /dev/null | head -n 1)" elif [ "${engine}" == "goldsrc" ]; then diff --git a/lgsm/modules/update_xnt.sh b/lgsm/modules/update_xnt.sh index 904b7b1a4..e6f88cc27 100755 --- a/lgsm/modules/update_xnt.sh +++ b/lgsm/modules/update_xnt.sh @@ -20,7 +20,7 @@ fn_update_localbuild() { check_status.sh # Send version command to Xonotic server. if [ "${status}" != "0" ]; then - tmux -L "${socketname}" send-keys -t "${sessionname}" "version" C-m > /dev/null 2>&1 + TERM=screen tmux -L "${socketname}" send-keys -t "${sessionname}" "version" C-m > /dev/null 2>&1 fn_sleep_time_1 else exitbypass=1 @@ -28,7 +28,7 @@ fn_update_localbuild() { fn_firstcommand_reset exitbypass=1 fn_sleep_time_5 - tmux -L "${socketname}" send-keys -t "${sessionname}" "version" C-m > /dev/null 2>&1 + TERM=screen tmux -L "${socketname}" send-keys -t "${sessionname}" "version" C-m > /dev/null 2>&1 exitbypass=1 command_stop.sh unset exitbypass