100 lines
2.2 KiB
Bash
Executable File
100 lines
2.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# startb: start a command in the background with journald or file logging fallback.
|
|
# Usage:
|
|
# startb [--log logfile] COMMAND [ARGS...]
|
|
# Environment:
|
|
# STARTB_LOGFILE=... to force a log file.
|
|
|
|
set -euo pipefail
|
|
|
|
# PATH may be incomplete from systemd login env; restore from interactive shell.
|
|
PATH=$(zsh -c -i 'echo $PATH')
|
|
export PATH
|
|
|
|
SCRIPT_NAME="${0##*/}"
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
Usage: ${SCRIPT_NAME} [--log logfile] COMMAND [ARGS...]
|
|
|
|
--log logfile Write logs to this file instead of journald.
|
|
Environment variable STARTB_LOGFILE can also provide a logfile path.
|
|
EOF
|
|
exit 1
|
|
}
|
|
|
|
if [ $# -lt 1 ]; then
|
|
usage
|
|
fi
|
|
|
|
LOG_FILE=${STARTB_LOGFILE:-}
|
|
|
|
if [ "$1" = "--log" ] || [ "$1" = "-l" ]; then
|
|
shift
|
|
if [ $# -lt 1 ]; then
|
|
echo "Error: --log requires a logfile path." >&2
|
|
usage
|
|
fi
|
|
LOG_FILE=$1
|
|
shift
|
|
fi
|
|
|
|
if [ $# -lt 1 ]; then
|
|
usage
|
|
fi
|
|
|
|
COMMAND=("$@")
|
|
UNIT_BASE=$(basename "${COMMAND[0]}")
|
|
UNIT_BASE=${UNIT_BASE:-cmd}
|
|
UNIT_NAME="${UNIT_BASE}-$(date +%Y%m%d_%H%M%S_%N)"
|
|
|
|
log_to_file() {
|
|
local path=$1
|
|
mkdir -p "$(dirname "$path")" 2>/dev/null || true
|
|
touch "$path" || {
|
|
echo "Failed to touch logfile: $path" >&2
|
|
return 1
|
|
}
|
|
|
|
nohup setsid "${COMMAND[@]}" >>"$path" 2>&1 &
|
|
local pid=$!
|
|
disown "$pid" 2>/dev/null || true
|
|
echo "$UNIT_NAME started in background (pid=$pid), logs: $path"
|
|
return 0
|
|
}
|
|
|
|
log_to_journal() {
|
|
# 不按雪叶那样写基本记录不到输出,懒得调了,直接屏蔽。
|
|
# if command -v systemd-run >/dev/null 2>&1; then
|
|
# systemd-run --user --scope --unit="$UNIT_NAME" -- "${COMMAND[@]}" >/dev/null 2>&1 &
|
|
# local pid=$!
|
|
# echo "$UNIT_NAME started in systemd scope (pid=$pid), journald logging enabled"
|
|
# return 0
|
|
# fi
|
|
|
|
if command -v systemd-cat >/dev/null 2>&1; then
|
|
nohup setsid systemd-cat -t "$UNIT_BASE" -- "${COMMAND[@]}" >/dev/null 2>&1 &
|
|
local pid=$!
|
|
disown "$pid" 2>/dev/null || true
|
|
echo "$UNIT_BASE started with systemd-cat (pid=$pid), journald logging enabled"
|
|
return 0
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
if [ -n "$LOG_FILE" ]; then
|
|
log_to_file "$LOG_FILE" || exit 1
|
|
exit 0
|
|
fi
|
|
|
|
if log_to_journal; then
|
|
exit 0
|
|
fi
|
|
|
|
# Fallback log path when journald is unavailable.
|
|
LOG_FILE="/tmp/${USER:-unknown}/startb/${UNIT_NAME}.log"
|
|
log_to_file "$LOG_FILE"
|
|
|
|
|