Add healthcheck.sh and update managed-windrose files
This commit is contained in:
1 parent
cdd3810bd4
commit
ee7c49b533
3 files changed
+252
-132
No files matched your search
+41
-30
@@ -1,39 +1,50 @@
|
|||||||
services:
|
services:
|
||||||
windrose:
|
windrose:
|
||||||
build: .
|
build: .
|
||||||
container_name: windrose-servermanager
|
container_name: managed-windrose
|
||||||
|
hostname: managed-windrose
|
||||||
|
restart: unless-stopped
|
||||||
|
stop_grace_period: 90s
|
||||||
|
network_mode: host
|
||||||
|
|
||||||
# IMPORTANT: Linux/TrueNAS paths ONLY
|
env_file:
|
||||||
volumes:
|
- .env
|
||||||
- /mnt/tank/windrose/server:/server:rw
|
|
||||||
- /mnt/tank/windrose/server/R5:/server/R5:rw
|
|
||||||
- /mnt/tank/windrose/data/Saved:/data/Saved:rw
|
|
||||||
|
|
||||||
ports:
|
|
||||||
- "27015:27015/udp"
|
|
||||||
- "27015:27015/tcp"
|
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
- WINEPREFIX=/data/wine/wineprefix
|
PUID: ${PUID:-1000}
|
||||||
- WINEARCH=win64
|
PGID: ${PGID:-1000}
|
||||||
- WINDROSE_HOME=/server
|
WINDROSE_APP_ID: ${WINDROSE_APP_ID:-4129620}
|
||||||
- WINDROSE_R5=/server/R5
|
STEAM_LOGIN: ${STEAM_LOGIN:-anonymous}
|
||||||
- SAVED_DIR=/data/Saved
|
STEAM_PASS: ${STEAM_PASS:-}
|
||||||
|
UPDATE_ON_START: ${UPDATE_ON_START:-true}
|
||||||
|
GENERATE_SETTINGS: ${GENERATE_SETTINGS:-true}
|
||||||
|
INVITE_CODE: ${INVITE_CODE:-}
|
||||||
|
SERVER_NAME: ${SERVER_NAME:-Managed Windrose Server}
|
||||||
|
SERVER_NOTE: ${SERVER_NOTE:-}
|
||||||
|
SERVER_PASSWORD: ${SERVER_PASSWORD:-}
|
||||||
|
MAX_PLAYERS: ${MAX_PLAYERS:-4}
|
||||||
|
P2P_PROXY_ADDRESS: ${P2P_PROXY_ADDRESS:-127.0.0.1}
|
||||||
|
MULTIHOME: ${MULTIHOME:-0.0.0.0}
|
||||||
|
WINEARCH: win64
|
||||||
|
WINEPREFIX: /home/steam/.wine
|
||||||
|
WINEDEBUG: -all
|
||||||
|
DISPLAY: ":99"
|
||||||
|
PORT: ${PORT:-7777}
|
||||||
|
QUERYPORT: ${QUERYPORT:-7778}
|
||||||
|
|
||||||
# Intel ARC GPU Vulkan
|
volumes:
|
||||||
- LIBVA_DRIVER_NAME=iHD
|
- /mnt/tank/windrose/data:/data
|
||||||
- VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/intel_icd.x86_64.json:/usr/share/vulkan/icd.d/intel_icd.i686.json
|
- /mnt/tank/windrose/steam-home:/home/steam
|
||||||
|
|
||||||
# DXVK overrides
|
healthcheck:
|
||||||
- WINEDLLOVERRIDES=d3d11,dxgi,d3d10core,d3d9=native,builtin
|
test: ["CMD-SHELL", "/healthcheck.sh"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 5
|
||||||
|
start_period: 300s
|
||||||
|
|
||||||
# GPU passthrough
|
logging:
|
||||||
devices:
|
driver: json-file
|
||||||
- /dev/dri:/dev/dri
|
options:
|
||||||
|
max-size: "20m"
|
||||||
# Required for Wine + GPU access
|
max-file: "5"
|
||||||
cap_add:
|
|
||||||
- SYS_ADMIN
|
|
||||||
|
|
||||||
tty: true
|
|
||||||
stdin_open: true
|
|
||||||
+36
-31
@@ -1,45 +1,50 @@
|
|||||||
# Dockerfile
|
|
||||||
FROM ubuntu:22.04
|
FROM ubuntu:22.04
|
||||||
|
|
||||||
|
LABEL org.opencontainers.image.source="https://gitea.theminisip.ca/mini-server-manager/managed-windrose" \
|
||||||
|
org.opencontainers.image.description="Managed Windrose Dedicated Server for Mini-Server-Manager" \
|
||||||
|
org.opencontainers.image.licenses="MIT" \
|
||||||
|
org.opencontainers.image.authors="Irken Laboratories"
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND=noninteractive
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
ENV WINEPREFIX=/data/wine/wineprefix
|
ENV USER=steam
|
||||||
ENV WINEARCH=win64
|
ENV HOME=/home/steam
|
||||||
ENV WINDROSE_HOME=/server
|
ENV STEAMCMDDIR=/opt/steamcmd
|
||||||
ENV WINDROSE_R5=/server/R5
|
ENV DISPLAY=:99
|
||||||
ENV SAVED_DIR=/data/Saved
|
ENV WINEDEBUG=-all
|
||||||
|
ENV LANG=en_US.UTF-8
|
||||||
|
ENV LC_ALL=en_US.UTF-8
|
||||||
|
|
||||||
# Install WineHQ (correct method for Ubuntu 22.04)
|
RUN dpkg --add-architecture i386 && \
|
||||||
RUN dpkg --add-architecture i386 \
|
apt update && \
|
||||||
&& apt-get update \
|
apt install -y \
|
||||||
&& apt-get install -y --no-install-recommends \
|
curl ca-certificates \
|
||||||
ca-certificates wget curl gnupg2 software-properties-common \
|
xvfb xauth \
|
||||||
xvfb x11vnc pulseaudio cabextract unzip p7zip-full \
|
wine64 wine32 winbind \
|
||||||
&& mkdir -pm755 /etc/apt/keyrings \
|
lib32gcc-s1 lib32stdc++6 \
|
||||||
&& wget -O /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key \
|
libc6:i386 libstdc++6:i386 \
|
||||||
&& wget -NP /etc/apt/sources.list.d/ https://dl.winehq.org/wine-builds/ubuntu/dists/jammy/winehq-jammy.sources \
|
libncurses5:i386 libtinfo5:i386 \
|
||||||
&& apt-get update \
|
locales \
|
||||||
&& apt-get install -y --install-recommends winehq-stable \
|
jq \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
procps \
|
||||||
|
|
||||||
# Intel ARC GPU + Vulkan support
|
|
||||||
RUN dpkg --add-architecture i386 \
|
|
||||||
&& apt-get update \
|
|
||||||
&& apt-get install -y --no-install-recommends \
|
|
||||||
mesa-vulkan-drivers mesa-vulkan-drivers:i386 \
|
mesa-vulkan-drivers mesa-vulkan-drivers:i386 \
|
||||||
libvulkan1 libvulkan1:i386 \
|
libvulkan1 libvulkan1:i386 \
|
||||||
intel-media-va-driver-non-free vainfo \
|
intel-media-va-driver-non-free vainfo \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Install DXVK 2.3 (runtime DLLs only)
|
RUN sed -i 's/^# \(en_US.UTF-8 UTF-8\)/\1/' /etc/locale.gen && locale-gen
|
||||||
RUN wget -O dxvk.tar.gz https://github.com/doitsujin/dxvk/releases/download/v2.3/dxvk-2.3.tar.gz \
|
RUN mkdir -p /tmp/.X11-unix && chmod 1777 /tmp/.X11-unix
|
||||||
&& tar -xvf dxvk.tar.gz \
|
RUN useradd -u 1000 -m -s /bin/bash steam
|
||||||
&& rm dxvk.tar.gz \
|
|
||||||
&& mv dxvk-2.3 /opt/dxvk
|
|
||||||
|
|
||||||
# Create directories for mounts
|
RUN mkdir -p /opt/steamcmd && \
|
||||||
RUN mkdir -p ${WINDROSE_HOME} ${WINDROSE_R5}
|
curl -sSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz \
|
||||||
|
| tar -xz -C /opt/steamcmd && \
|
||||||
|
chown -R steam:steam /opt/steamcmd /home/steam
|
||||||
|
|
||||||
|
RUN mkdir -p /data && chown -R steam:steam /data
|
||||||
|
|
||||||
COPY entrypoint.sh /entrypoint.sh
|
COPY entrypoint.sh /entrypoint.sh
|
||||||
RUN chmod +x /entrypoint.sh
|
COPY healthcheck.sh /healthcheck.sh
|
||||||
|
RUN chmod +x /entrypoint.sh /healthcheck.sh
|
||||||
|
|
||||||
|
WORKDIR /home/steam
|
||||||
ENTRYPOINT ["/entrypoint.sh"]
|
ENTRYPOINT ["/entrypoint.sh"]
|
||||||
+175
-71
@@ -1,87 +1,191 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
WINEPREFIX=${WINEPREFIX:-/data/wine/wineprefix}
|
APPID=${WINDROSE_APP_ID:-4129620}
|
||||||
WINDROSE_HOME=${WINDROSE_HOME:-/server}
|
SERVERDIR=${SERVERDIR:-/data}
|
||||||
WINDROSE_R5=${WINDROSE_R5:-/server/R5}
|
STEAM_HOME=${STEAM_HOME:-/home/steam}
|
||||||
SAVED_DIR=${SAVED_DIR:-/data/Saved}
|
WINEPREFIX=${WINEPREFIX:-$STEAM_HOME/.wine}
|
||||||
|
STEAM_LOGIN=${STEAM_LOGIN:-anonymous}
|
||||||
|
STEAM_PASS=${STEAM_PASS:-}
|
||||||
|
UPDATE_ON_START=${UPDATE_ON_START:-true}
|
||||||
|
GENERATE_SETTINGS=${GENERATE_SETTINGS:-true}
|
||||||
|
PUID=${PUID:-1000}
|
||||||
|
PGID=${PGID:-1000}
|
||||||
|
|
||||||
SERVER_EXE="${WINDROSE_R5}/Binaries/Win64/WindroseServer-Win64-Shipping.exe"
|
PORT=${PORT:-7777}
|
||||||
|
QUERYPORT=${QUERYPORT:-7778}
|
||||||
|
MULTIHOME=${MULTIHOME:-0.0.0.0}
|
||||||
|
|
||||||
export WINEDEBUG=-all
|
INVITE_CODE=${INVITE_CODE:-}
|
||||||
export DISPLAY=
|
SERVER_NAME=${SERVER_NAME:-}
|
||||||
export XDG_RUNTIME_DIR=/tmp/runtime-wine
|
SERVER_NOTE=${SERVER_NOTE:-}
|
||||||
mkdir -p "$XDG_RUNTIME_DIR"
|
SERVER_PASSWORD=${SERVER_PASSWORD:-}
|
||||||
|
MAX_PLAYERS=${MAX_PLAYERS:-4}
|
||||||
|
P2P_PROXY_ADDRESS=${P2P_PROXY_ADDRESS:-127.0.0.1}
|
||||||
|
FIRST_RUN_TIMEOUT=${FIRST_RUN_TIMEOUT:-180}
|
||||||
|
|
||||||
# Intel ARC Vulkan ICDs
|
SERVER_DESC="$SERVERDIR/R5/ServerDescription.json"
|
||||||
export VK_ICD_FILENAMES="/usr/share/vulkan/icd.d/intel_icd.x86_64.json:/usr/share/vulkan/icd.i686.json"
|
SERVER_PID=""
|
||||||
export LIBVA_DRIVER_NAME=iHD
|
XVFB_PID=""
|
||||||
|
|
||||||
DXVK_32="/opt/dxvk/x32"
|
log() { echo "[windrose] $*"; }
|
||||||
DXVK_64="/opt/dxvk/x64"
|
quote() { printf '%q' "$1"; }
|
||||||
|
run_as_steam() { su -s /bin/bash steam -c "$*"; }
|
||||||
|
|
||||||
# Initialize wineprefix if missing
|
ensure_user_mapping() {
|
||||||
if [ ! -d "$WINEPREFIX" ] || [ ! -f "$WINEPREFIX/system.reg" ]; then
|
groupmod -o -g "$PGID" steam 2>/dev/null || true
|
||||||
echo "Initializing wineprefix at $WINEPREFIX"
|
usermod -o -u "$PUID" steam 2>/dev/null || true
|
||||||
|
mkdir -p "$SERVERDIR" "$STEAM_HOME"
|
||||||
|
chown -R steam:steam /opt/steamcmd "$STEAM_HOME" "$SERVERDIR" 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup_xvfb() {
|
||||||
|
if [ -n "$XVFB_PID" ] && kill -0 "$XVFB_PID" 2>/dev/null; then
|
||||||
|
kill "$XVFB_PID" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
rm -f /tmp/.X99-lock 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
shutdown_server() {
|
||||||
|
log "Stopping Windrose dedicated server"
|
||||||
|
pkill -TERM -u steam -f 'WindroseServer-Win64-Shipping.exe' 2>/dev/null || true
|
||||||
|
pkill -TERM -u steam -f 'wineserver' 2>/dev/null || true
|
||||||
|
for _ in $(seq 1 60); do
|
||||||
|
if ! pgrep -u steam -f 'WindroseServer-Win64-Shipping.exe|wineserver' >/dev/null 2>&1; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
pkill -KILL -u steam -f 'WindroseServer-Win64-Shipping.exe|wineserver' 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
trap 'shutdown_server; exit 0' TERM INT
|
||||||
|
trap 'cleanup_xvfb' EXIT
|
||||||
|
|
||||||
|
init_xvfb() {
|
||||||
|
rm -f /tmp/.X99-lock 2>/dev/null || true
|
||||||
|
Xvfb :99 -screen 0 1024x768x16 -nolisten tcp >/dev/null 2>&1 &
|
||||||
|
XVFB_PID=$!
|
||||||
|
sleep 1
|
||||||
|
}
|
||||||
|
|
||||||
|
init_wine() {
|
||||||
mkdir -p "$WINEPREFIX"
|
mkdir -p "$WINEPREFIX"
|
||||||
wineboot --init || true
|
chown -R steam:steam "$STEAM_HOME" 2>/dev/null || true
|
||||||
|
if [ ! -f "$WINEPREFIX/system.reg" ]; then
|
||||||
|
log "Initializing Wine prefix"
|
||||||
|
run_as_steam "WINEPREFIX=$(quote "$WINEPREFIX") wineboot -i >/dev/null 2>&1 || true"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
echo "Installing DXVK DLLs into wineprefix..."
|
update_server() {
|
||||||
WIN_SYS32="$WINEPREFIX/drive_c/windows/system32"
|
if [ "$UPDATE_ON_START" != "true" ]; then
|
||||||
WIN_SYSWOW64="$WINEPREFIX/drive_c/windows/syswow64"
|
log "UPDATE_ON_START=false, skipping SteamCMD update"
|
||||||
|
return
|
||||||
mkdir -p "$WIN_SYS32" "$WIN_SYSWOW64"
|
|
||||||
|
|
||||||
cp "$DXVK_64"/*.dll "$WIN_SYS32"/
|
|
||||||
cp "$DXVK_32"/*.dll "$WIN_SYSWOW64"/
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Force DXVK to be used
|
local login_cmd
|
||||||
export WINEDLLOVERRIDES="d3d11,dxgi,d3d10core,d3d9=native,builtin"
|
if [ "$STEAM_LOGIN" = "anonymous" ]; then
|
||||||
|
login_cmd='+login anonymous'
|
||||||
mkdir -p "$SAVED_DIR"
|
elif [ -n "$STEAM_PASS" ]; then
|
||||||
|
login_cmd="+login $(quote "$STEAM_LOGIN") $(quote "$STEAM_PASS")"
|
||||||
case "${1:-}" in
|
else
|
||||||
run-server)
|
login_cmd="+login $(quote "$STEAM_LOGIN")"
|
||||||
echo "Starting Windrose dedicated server..."
|
|
||||||
|
|
||||||
# ---------------------------------------------------------
|
|
||||||
# AUTOMATIC INSTALLER: Install Windrose if missing
|
|
||||||
# ---------------------------------------------------------
|
|
||||||
if [ ! -f "$SERVER_EXE" ]; then
|
|
||||||
echo "Windrose server binary missing — installing via SteamCMD..."
|
|
||||||
mkdir -p "$WINDROSE_R5"
|
|
||||||
|
|
||||||
/root/steamcmd/steamcmd.sh \
|
|
||||||
+login anonymous \
|
|
||||||
+force_install_dir "$WINDROSE_R5" \
|
|
||||||
+app_update 4129620 validate \
|
|
||||||
+quit
|
|
||||||
|
|
||||||
echo "Windrose server installation complete."
|
|
||||||
fi
|
fi
|
||||||
# ---------------------------------------------------------
|
|
||||||
|
|
||||||
if [ ! -f "$SERVER_EXE" ]; then
|
log "Updating or validating server files via SteamCMD (AppID $APPID)"
|
||||||
echo "ERROR: Windrose server binary still not found after install:"
|
run_as_steam "mkdir -p $(quote "$SERVERDIR") && /opt/steamcmd/steamcmd.sh +force_install_dir $(quote "$SERVERDIR") $login_cmd +app_update $(quote "$APPID") validate +quit"
|
||||||
echo " $SERVER_EXE"
|
}
|
||||||
|
|
||||||
|
find_server_exe() {
|
||||||
|
find "$SERVERDIR" -iname 'WindroseServer-Win64-Shipping.exe' 2>/dev/null | head -n 1 || true
|
||||||
|
}
|
||||||
|
|
||||||
|
first_run_generate_config() {
|
||||||
|
local exe="$1"
|
||||||
|
if [ "$GENERATE_SETTINGS" != "true" ] || [ -f "$SERVER_DESC" ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "First run detected, generating default server config"
|
||||||
|
run_as_steam "WINEPREFIX=$(quote "$WINEPREFIX") wine $(quote "$exe") -log -MULTIHOME=$(quote "$MULTIHOME") -PORT=$(quote "$PORT") -QUERYPORT=$(quote "$QUERYPORT") >/tmp/windrose-first-run.log 2>&1" &
|
||||||
|
local warmup_pid=$!
|
||||||
|
|
||||||
|
local count=0
|
||||||
|
while [ ! -f "$SERVER_DESC" ] && [ "$count" -lt "$FIRST_RUN_TIMEOUT" ]; do
|
||||||
|
sleep 1
|
||||||
|
count=$((count + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
kill "$warmup_pid" 2>/dev/null || true
|
||||||
|
wait "$warmup_pid" 2>/dev/null || true
|
||||||
|
pkill -TERM -u steam -f 'wineserver' 2>/dev/null || true
|
||||||
|
|
||||||
|
if [ ! -f "$SERVER_DESC" ]; then
|
||||||
|
log "WARNING: ServerDescription.json was not generated within ${FIRST_RUN_TIMEOUT}s"
|
||||||
|
log "Wine output:"
|
||||||
|
tail -n 40 /tmp/windrose-first-run.log 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
patch_server_config() {
|
||||||
|
if [ "$GENERATE_SETTINGS" != "true" ]; then
|
||||||
|
log "GENERATE_SETTINGS=false, skipping JSON patching"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
if [ ! -f "$SERVER_DESC" ]; then
|
||||||
|
log "ServerDescription.json not found, skipping patch"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "Patching ServerDescription.json from environment"
|
||||||
|
tr -d '\r' < "$SERVER_DESC" | jq \
|
||||||
|
--arg invite "$INVITE_CODE" \
|
||||||
|
--arg name "$SERVER_NAME" \
|
||||||
|
--arg note "$SERVER_NOTE" \
|
||||||
|
--arg password "$SERVER_PASSWORD" \
|
||||||
|
--arg proxy "$P2P_PROXY_ADDRESS" \
|
||||||
|
--argjson maxplayers "$MAX_PLAYERS" \
|
||||||
|
'
|
||||||
|
.ServerDescription_Persistent.P2pProxyAddress = $proxy |
|
||||||
|
if $invite != "" then .ServerDescription_Persistent.InviteCode = $invite else . end |
|
||||||
|
if $name != "" then .ServerDescription_Persistent.ServerName = $name else . end |
|
||||||
|
if $note != "" then .ServerDescription_Persistent.Note = $note else . end |
|
||||||
|
if $password != "" then
|
||||||
|
.ServerDescription_Persistent.IsPasswordProtected = true |
|
||||||
|
.ServerDescription_Persistent.Password = $password
|
||||||
|
else
|
||||||
|
.ServerDescription_Persistent.IsPasswordProtected = false |
|
||||||
|
.ServerDescription_Persistent.Password = ""
|
||||||
|
end |
|
||||||
|
.ServerDescription_Persistent.MaxPlayerCount = $maxplayers
|
||||||
|
' > "$SERVER_DESC.tmp"
|
||||||
|
mv "$SERVER_DESC.tmp" "$SERVER_DESC"
|
||||||
|
chown steam:steam "$SERVER_DESC" 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
start_server() {
|
||||||
|
local exe="$1"
|
||||||
|
log "Starting Windrose dedicated server"
|
||||||
|
log "Executable: $exe"
|
||||||
|
log "Bind: $MULTIHOME Port: $PORT QueryPort: $QUERYPORT"
|
||||||
|
run_as_steam "WINEPREFIX=$(quote "$WINEPREFIX") wine $(quote "$exe") -log -MULTIHOME=$(quote "$MULTIHOME") -PORT=$(quote "$PORT") -QUERYPORT=$(quote "$QUERYPORT")" &
|
||||||
|
SERVER_PID=$!
|
||||||
|
wait "$SERVER_PID"
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_user_mapping
|
||||||
|
init_xvfb
|
||||||
|
init_wine
|
||||||
|
update_server
|
||||||
|
|
||||||
|
SERVER_EXE=$(find_server_exe)
|
||||||
|
if [ -z "$SERVER_EXE" ]; then
|
||||||
|
log "ERROR: Windrose server executable not found under $SERVERDIR"
|
||||||
|
find "$SERVERDIR" -maxdepth 4 2>/dev/null || true
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cd "$(dirname "$SERVER_EXE")"
|
first_run_generate_config "$SERVER_EXE"
|
||||||
|
patch_server_config
|
||||||
exec wine "$SERVER_EXE" \
|
start_server "$SERVER_EXE"
|
||||||
-log \
|
|
||||||
-unattended \
|
|
||||||
-nosteam \
|
|
||||||
-savedir "$SAVED_DIR"
|
|
||||||
;;
|
|
||||||
|
|
||||||
bash)
|
|
||||||
exec /bin/bash
|
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
|
||||||
exec "$@"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
Reference in new issue
Block a user