又用 vscode copilot 重写 startb
至少这次可读性还不错。
This commit is contained in:
121
bin/startb
121
bin/startb
@@ -1,40 +1,99 @@
|
||||
#!/bin/bash
|
||||
# like `start /b` in Windows CMD.
|
||||
#!/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.
|
||||
|
||||
# PATH 不完整问题:
|
||||
# 根据 niri 启动方式的不同,niri 读到的环境变量可能也不一样。
|
||||
# - tty 进终端再 niri-session 拉起来大概是最完整的。毕竟已经加载 .xxxrc 了嘛。
|
||||
# - 而像我这样用 sddm 进的 niri,由于直接从 systemd 启动,中间也没有任何机会更新 PATH,相比就最麻烦了。
|
||||
# 根据谷鸽 AI 的回答,我这种情况只能在 ~/.config/environment.d/ 里静态补上环境变量。
|
||||
# 之前不懂的时候用的是如下的奇技淫巧:
|
||||
set -euo pipefail
|
||||
|
||||
# PATH=$(zsh -c -i 'echo $PATH')
|
||||
# export PATH
|
||||
# PATH may be incomplete from systemd login env; restore from interactive shell.
|
||||
PATH=$(zsh -c -i 'echo $PATH')
|
||||
export PATH
|
||||
|
||||
# https://vescrity.github.io/post/systemd-desktop-suspend/
|
||||
#systemd-run --user --scope --slice=YukiLauncher.slice --unit="$1-$$".scope /bin/sh -c '"$@"' _ "$@"
|
||||
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
|
||||
echo "Usage: daemon-run COMMAND [ARGS...]"
|
||||
exit 1
|
||||
usage
|
||||
fi
|
||||
|
||||
UNIT_NAME="${1##*/}-$(date +%s%N)"
|
||||
ENV_ARGS=(
|
||||
--setenv=PATH="$PATH"
|
||||
--setenv=NVM_DIR="$NVM_DIR"
|
||||
--setenv=NVM_BIN="$NVM_BIN"
|
||||
)
|
||||
LOG_FILE=${STARTB_LOGFILE:-}
|
||||
|
||||
systemd-run --user \
|
||||
"${ENV_ARGS[@]}" \
|
||||
--working-directory="$PWD" \
|
||||
--slice=StartProcess.slice \
|
||||
--unit="$UNIT_NAME" \
|
||||
--collect \
|
||||
-- /bin/sh -c 'exec "$@"' _ "$@"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Logs : journalctl --user -u $UNIT_NAME -f"
|
||||
echo "Note : '$UNIT_NAME' will auto-destruct on exit."
|
||||
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_NAME" -- "${COMMAND[@]}" >/dev/null 2>&1 &
|
||||
local pid=$!
|
||||
disown "$pid" 2>/dev/null || true
|
||||
echo "$UNIT_NAME 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"
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user