重写 startb;补点中文注释;删减多余的定时模板
为啥又中文了?英文太长,中英夹杂键起来别扭。 不会真有人用我原始人般的配置吧?
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
# Proxy, set in environment.d?
|
||||
http_proxy="http://127.0.0.1:7890/"
|
||||
https_proxy="http://127.0.0.1:7890/"
|
||||
|
||||
# also needs manual configuration in firefox.
|
||||
# firefox 记得单独配一次.
|
||||
no_proxy="127.*,192.168.*,10.147.17.*"
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
binds {
|
||||
Mod+F1 { show-hotkey-overlay; }
|
||||
// 芝士快捷键表。我自己也很难说能熟练用,所以从`config.kdl`里拆出来了。所幸它支持 include。
|
||||
|
||||
Mod+Return hotkey-overlay-title="Terminal (foot)" { spawn "foot"; }
|
||||
Mod+F9 hotkey-overlay-title="Browser (chrome)" { spawn "google-chrome-stable"; }
|
||||
Mod+E hotkey-overlay-title="Explorer (yazi)" { spawn "foot" "yazi"; }
|
||||
binds {
|
||||
Mod+F1 hotkey-overlay-title="显示帮助喵" { show-hotkey-overlay; }
|
||||
|
||||
Mod+Return hotkey-overlay-title="终端 (foot)" { spawn "foot"; }
|
||||
Mod+F9 hotkey-overlay-title="浏览器 (chrome)" { spawn "google-chrome-stable"; }
|
||||
Mod+E hotkey-overlay-title="文件管理器 (yazi)" { spawn "foot" "yazi"; }
|
||||
//Shift+Mod+Return hotkey-overlay-title="Steam" { spawn "steam"; }
|
||||
|
||||
Mod+F12 hotkey-overlay-title="Open Projects ... (VSCode)" { spawn ".fuzzel-vscode"; }
|
||||
Mod+Space hotkey-overlay-title="Run a command ... (fuzzel)" { spawn ".fuzzel-startb"; }
|
||||
Mod+F12 hotkey-overlay-title="打开桌面项目 ... (VSCode)" { spawn ".fuzzel-vscode"; }
|
||||
Mod+Space hotkey-overlay-title="运行命令 ... (fuzzel)" { spawn ".fuzzel-startb"; }
|
||||
|
||||
// Applications such as remote-desktop clients and software KVM switches may
|
||||
// request that niri stops processing the keyboard shortcuts defined here
|
||||
@@ -18,9 +20,9 @@ binds {
|
||||
// The allow-inhibiting=false property can be applied to other binds as well,
|
||||
// which ensures niri always processes them, even when an inhibitor is active.
|
||||
Mod+Alt+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; }
|
||||
XF86PowerOff hotkey-overlay-title="Exit niri" { quit; }
|
||||
Super+Escape hotkey-overlay-title="Lock the Screen (gtklock)" { spawn "gtklock" "-d"; }
|
||||
Mod+Delete hotkey-overlay-title="Lock screen and Hibernate ..." allow-when-locked=true {
|
||||
XF86PowerOff hotkey-overlay-title="大退(注销)" { quit; }
|
||||
Super+Escape hotkey-overlay-title="锁屏 (gtklock)" { spawn "gtklock" "-d"; }
|
||||
Mod+Delete hotkey-overlay-title="锁屏并休眠 ..." allow-when-locked=true {
|
||||
spawn-sh "(pgrep gtklock || gtklock -d) && sleep 1.5 && systemctl hibernate";
|
||||
}
|
||||
|
||||
@@ -40,6 +42,7 @@ binds {
|
||||
XF86MonBrightnessUp allow-when-locked=true { spawn "brightnessctl" "--class=backlight" "set" "+5%"; }
|
||||
XF86MonBrightnessDown allow-when-locked=true { spawn "brightnessctl" "--class=backlight" "set" "5%-"; }
|
||||
|
||||
// 有些键位懒得补汉化说明,自己摁两下就知道了。
|
||||
Alt+Tab hotkey-overlay-title=null repeat=false { toggle-overview; }
|
||||
Alt+F4 { close-window; }
|
||||
|
||||
@@ -212,7 +215,7 @@ binds {
|
||||
// Mod+Shift+Space { switch-layout "prev"; }
|
||||
|
||||
Print hotkey-overlay-title=null { screenshot-screen; }
|
||||
Mod+Shift+S { screenshot; }
|
||||
Mod+Shift+S hotkey-overlay-title="截取矩形画面(和 Win11 类似)" { screenshot; }
|
||||
Alt+Print { screenshot-window; }
|
||||
|
||||
// Powers off the monitors. To turn them back on, do any input like
|
||||
@@ -1,3 +1,5 @@
|
||||
// 这是窗口布局表。由于经常改,也拆出来了。
|
||||
|
||||
window-rule {
|
||||
geometry-corner-radius 6
|
||||
clip-to-geometry true
|
||||
@@ -41,7 +41,7 @@ input {
|
||||
}
|
||||
|
||||
warp-mouse-to-focus
|
||||
// also needs ignore in `/etc/systemd/logind.conf`.
|
||||
// 还需要在`/etc/systemd/logind.conf`里屏蔽关机键行为.
|
||||
disable-power-key-handling
|
||||
focus-follows-mouse max-scroll-amount="0%"
|
||||
}
|
||||
@@ -174,10 +174,12 @@ animations {
|
||||
}
|
||||
}
|
||||
|
||||
include "config.window.kdl"
|
||||
include "config.keyboard.kdl"
|
||||
// 我看雪叶是把能拆的大板块都拆得一干二净,但就我这份配置而言,拆两份常用的出来已经足矣了。
|
||||
// 部分视觉效果拆出去可能还会失效(比如窗口边框)。
|
||||
include "config-window.kdl"
|
||||
include "config-keyboard.kdl"
|
||||
|
||||
// spawn-at-startup "waybar"
|
||||
// spawn-at-startup "waybar" // 建议交给 systemctl --user,它自己没法热重载。
|
||||
// spawn-sh-at-startup "wl-paste --watch cliphist store"
|
||||
spawn-at-startup "swww-daemon"
|
||||
spawn-at-startup "swww-daemon" "--namespace" "blur"
|
||||
@@ -202,5 +204,6 @@ gestures {
|
||||
|
||||
prefer-no-csd
|
||||
|
||||
// 我自己搞了个软链接,把截图丢进 tmpfs 里了。参见 .zshrc。
|
||||
screenshot-path "~/.tmp/Screenshots/%Y-%m-%d %H-%M-%S.png"
|
||||
// screenshot-path null
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# 像这种有明显时间规律的定时任务我懒得专门搞配套。不觉得 timer 非得跟 service 同名搞绑定很啰嗦吗?
|
||||
# 我完全可以 on-hourly@renew-wallpaper.timer、on-hourly@webapi-health-check.timer 嘛。
|
||||
# 当然这样也算不上简洁,但至少不需要另装个 cron(arch 不自带)。
|
||||
|
||||
[Unit]
|
||||
Description=Run %i hourly
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
[Unit]
|
||||
Description=Run %i monthly
|
||||
|
||||
[Timer]
|
||||
OnCalendar=monthly
|
||||
RandomizedDelaySec=5m
|
||||
AccuracySec=5s
|
||||
Persistent=true
|
||||
Unit=%i.service
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
@@ -1,12 +0,0 @@
|
||||
[Unit]
|
||||
Description=Run %i weekly
|
||||
|
||||
[Timer]
|
||||
OnCalendar=weekly
|
||||
RandomizedDelaySec=2m
|
||||
AccuracySec=2s
|
||||
Persistent=true
|
||||
Unit=%i.service
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
@@ -3,6 +3,7 @@
|
||||
"modules-left": [
|
||||
"niri/workspaces",
|
||||
"niri/window"
|
||||
// 我参考的那两人还用 sway,甚至大杂烩。而我只知道 niri,甚至一度也不想知道(不习惯)。
|
||||
],
|
||||
"modules-center": [
|
||||
"clock"
|
||||
@@ -41,6 +42,7 @@
|
||||
"Yazi: (.*)": "$1"
|
||||
}
|
||||
},
|
||||
// 这玩意说实话没想象中那么好用,但移植雪叶那个脚本,效果甚至还没这个好。
|
||||
"mpris": {
|
||||
"format": "{status_icon} {title}",
|
||||
"format-stopped": "",
|
||||
@@ -59,6 +61,7 @@
|
||||
"tray": {
|
||||
"spacing": 12
|
||||
},
|
||||
// 忘记用哪个工具确定设备节点了。实在不行终端开 yazi 来回翻。
|
||||
"temperature": {
|
||||
// "thermal-zone": 1,
|
||||
"hwmon-path-abs": "/sys/devices/platform/coretemp.0/hwmon",
|
||||
|
||||
@@ -2,5 +2,6 @@
|
||||
default=gnome;gtk;
|
||||
org.freedesktop.impl.portal.Access=gtk
|
||||
org.freedesktop.impl.portal.Notification=gtk
|
||||
# gnome 密码框太丑了。
|
||||
org.freedesktop.impl.portal.Secret=kwallet
|
||||
org.freedesktop.impl.portal.FileChooser=gtk
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
*.tar.zst
|
||||
fake-nautilus/**/
|
||||
.config/environment.d/[^0-9]*.conf
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# to clear history of shells easily operating filesystem.
|
||||
# also powershell/PSReadLine -> /tmp/$USER/terminal
|
||||
# 重启自动清空终端记录。毕竟万一露出什么不太好的关键词就丸辣。
|
||||
# zsh (HISTFILE) => /tmp/$USER/terminal/zsh_history
|
||||
# bash (HISTFILE) => /tmp/$USER/terminal/bash_history
|
||||
# pwsh (.local/share/powershell/PSReadLine) -> /tmp/$USER/terminal
|
||||
mkdir -p /tmp/$USER/terminal
|
||||
|
||||
# avoid dumplicate env appending.
|
||||
# 本意是为了防止 PATH 重复记录(算是我的强迫症吧),现在没必要了。
|
||||
# [[ -f /run/user/$UID/.zshlogon ]] && return
|
||||
# touch /run/user/$UID/.zshlogon
|
||||
|
||||
|
||||
2
.zshrc
2
.zshrc
@@ -142,7 +142,7 @@ unset key
|
||||
# To customize prompt, run `p10k configure` or edit ~/.p10k.zsh.
|
||||
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
|
||||
|
||||
# USER MANUAL CONFIGS
|
||||
# 俺的配置
|
||||
|
||||
# https://unix.stackexchange.com/questions/608842/zshrc-export-gpg-tty-tty-says-not-a-tty
|
||||
export GPG_TTY=$TTY
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
#!/usr/bin/env python
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
# Copyright © 2021 mpan; <https://mpan.pl/>; CC0 1.0 (THIS SCRIPT!)
|
||||
# Context: <https://bbs.archlinux.org/viewtopic.php?id=269453>
|
||||
# Reference: https://github.com/wogscpar/upower-python
|
||||
# Arch 论坛贴: <https://bbs.archlinux.org/viewtopic.php?id=269453>
|
||||
# UPower 实现: https://github.com/wogscpar/upower-python
|
||||
|
||||
# -*- encoding: utf-8 -*-
|
||||
# @File : .battery-warn
|
||||
# @Time : 2025/12/29 00:32:53
|
||||
# @Author : SilverAg.L
|
||||
|
||||
# bash pipeline was still too complicated.
|
||||
# Dependencies (pacman): python-dbus, libnotify, pipewire-audio
|
||||
# 搁 bash 折腾管道还是太原始了。
|
||||
# 包依赖 (pacman): python-dbus, libnotify, pipewire-audio
|
||||
|
||||
import dbus
|
||||
|
||||
@@ -18,11 +18,12 @@ from os import getenv
|
||||
from subprocess import run as start_process
|
||||
|
||||
# region config
|
||||
# 哪怕设备名也不稳定。pipewire 滚了几轮,桌面扬声器居然不见了。
|
||||
# AUD_OUT_EMB = ( # my laptop embedded speaker
|
||||
# "alsa_output.pci-0000_00_1f"
|
||||
# ".3-platform-skl_hda_dsp_generic.HiFi__Speaker__sink"
|
||||
# )
|
||||
# better searched by editor like VSCode.
|
||||
# 环境变量展开这一块。同时也是为了查找起来方便。毕竟已经有 gtklock 这个例外了。
|
||||
AUD_FILE = "~/.local/share/.low_power.wav".replace("~", getenv("HOME"), 1)
|
||||
# endregion config
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/bash
|
||||
option=$(fuzzel --dmenu --prompt-only="Run command: ")
|
||||
[ -z "$option" ] || startb -- $option
|
||||
[ -z "$option" ] || startb $option
|
||||
|
||||
@@ -15,4 +15,4 @@ for item in $(ls $desktop); do
|
||||
done
|
||||
|
||||
fsarg=$(echo -en "$options" | fuzzel --dmenu --prompt="Open with VSCode: Desktop/")
|
||||
[ -z "$fsarg" ] || startb -- code "$desktop/$fsarg"
|
||||
[ -z "$fsarg" ] || startb code "$desktop/$fsarg"
|
||||
|
||||
308
bin/startb
308
bin/startb
@@ -1,295 +1,45 @@
|
||||
#!/bin/bash
|
||||
# like `start /b` in Windows CMD.
|
||||
|
||||
# goddamn nvm-sh !!!
|
||||
# have to update PATH before launch
|
||||
PATH=$(zsh -c -i 'echo $PATH')
|
||||
export PATH
|
||||
# PATH 不完整问题:
|
||||
# 根据 niri 启动方式的不同,niri 读到的环境变量可能也不一样。
|
||||
# - tty 进终端再 niri-session 拉起来大概是最完整的。毕竟已经加载 .xxxrc 了嘛。
|
||||
# - 而像我这样用 sddm 进的 niri,由于直接从 systemd-user 启动,中间也没有任何机会更新 PATH,相比就最麻烦了。
|
||||
# 根据谷鸽 AI 的回答,我这种情况只能在 ~/.config/environment.d/ 里静态补上环境变量。
|
||||
# 之前不懂的时候用的是如下的奇技淫巧:
|
||||
|
||||
# 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 '"$@"' _ "$@"
|
||||
|
||||
# Generated by GitHub Copilot.
|
||||
# start-bg-journal.sh - start a command as a detached daemon and send stdout/stderr to systemd-journald
|
||||
#
|
||||
# Features:
|
||||
# - Sends stdout+stderr to journald using systemd-cat when available.
|
||||
# - Falls back to writing into a logfile if systemd-cat isn't present or if --log is passed.
|
||||
# - Uses setsid to detach, closes inherited file descriptors (best-effort),
|
||||
# redirects stdin to /dev/null, and execs the target command.
|
||||
# - Supports PID file, umask, and a syslog identifier (tag) and priority for journald.
|
||||
# - Uses positional args ($@) for the command; uses $$ in auto-generated names and prints the child PID ($!).
|
||||
#
|
||||
# Usage:
|
||||
# start-bg-journal.sh [ -t TAG ] [ -r PRIORITY ] [ -l LOGFILE | -d LOGDIR ] [ -p PIDFILE ] [ -u UMASK ] -- command [args...]
|
||||
#
|
||||
# Examples:
|
||||
# ./start-bg-journal.sh -t myapp -- /usr/bin/myapp --config /etc/myapp.conf
|
||||
# ./start-bg-journal.sh -l ./my.log -- /usr/bin/myapp arg1 arg2
|
||||
# ./start-bg-journal.sh -p /run/myapp.pid -t myapp -r info -- /usr/bin/myapp
|
||||
set -euo pipefail
|
||||
|
||||
progname=$(basename "$0")
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $progname [ -t TAG ] [ -r PRIORITY ] [ -l LOGFILE | -d LOGDIR ] [ -p PIDFILE ] [ -u UMASK ] -- command [args...]
|
||||
|
||||
Start command [args...] as a background daemon, sending stdout+stderr to systemd-journald (via systemd-cat)
|
||||
when available. If systemd-cat is not available or if -l/--log is provided, logs are written to a logfile.
|
||||
|
||||
Options:
|
||||
-t, --tag TAG Tag / SYSLOG_IDENTIFIER used by systemd-cat (default: basename(command))
|
||||
-r, --priority PRIO Journal priority (emerg, alert, crit, err, warning, notice, info, debug)
|
||||
-l, --log LOGFILE Write stdout+stderr to LOGFILE instead of journald
|
||||
-d, --dir LOGDIR Directory for autogenerated log files (default: /tmp/$USER/runner)
|
||||
-p, --pidfile PATH Write daemon PID to PATH
|
||||
-u, --umask UMASK Set umask for the daemon (default: 0022)
|
||||
-h, --help Show this help and exit
|
||||
|
||||
When no -l is provided and journald is available, output goes to journald.
|
||||
When -l is not provided and journald is not available, a logfile is auto-generated:
|
||||
<LOGDIR>/<command>.<YYYYMMDD-HHMMSS>.pid<$$>.log
|
||||
EOF
|
||||
if [ $# -lt 1 ]; then
|
||||
echo "Usage: daemon-run COMMAND [ARGS...]"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Defaults
|
||||
logdir="/tmp/$USER/runner"
|
||||
logfile=""
|
||||
pidfile=""
|
||||
umask_val="0022"
|
||||
tag=""
|
||||
priority=""
|
||||
|
||||
# Parse options up to --
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-t|--tag)
|
||||
if [[ $# -lt 2 ]]; then echo "Missing argument for $1"; usage; fi
|
||||
tag="$2"; shift 2 ;;
|
||||
-r|--priority)
|
||||
if [[ $# -lt 2 ]]; then echo "Missing argument for $1"; usage; fi
|
||||
priority="$2"; shift 2 ;;
|
||||
-l|--log)
|
||||
if [[ $# -lt 2 ]]; then echo "Missing argument for $1"; usage; fi
|
||||
logfile="$2"; shift 2 ;;
|
||||
-d|--dir)
|
||||
if [[ $# -lt 2 ]]; then echo "Missing argument for $1"; usage; fi
|
||||
logdir="$2"; shift 2 ;;
|
||||
-p|--pidfile)
|
||||
if [[ $# -lt 2 ]]; then echo "Missing argument for $1"; usage; fi
|
||||
pidfile="$2"; shift 2 ;;
|
||||
-u|--umask)
|
||||
if [[ $# -lt 2 ]]; then echo "Missing argument for $1"; usage; fi
|
||||
umask_val="$2"; shift 2 ;;
|
||||
-h|--help)
|
||||
usage ;;
|
||||
--)
|
||||
shift; break ;;
|
||||
-*)
|
||||
echo "Unknown option: $1"; usage ;;
|
||||
*)
|
||||
break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ $# -eq 0 ]]; then
|
||||
echo "Error: no command specified."
|
||||
usage
|
||||
fi
|
||||
|
||||
# Build command array from remaining args.
|
||||
cmd=( "$@" )
|
||||
cmd_basename=$(basename "${cmd[0]}")
|
||||
timestamp=$(date +%Y%m%d-%H%M%S)
|
||||
CMD_NAME="${1##*/}"
|
||||
UNIT_NAME="${CMD_NAME}-$(date +%s%N)"
|
||||
|
||||
# If tag not set, default to command basename
|
||||
if [[ -z "$tag" ]]; then
|
||||
tag="${cmd_basename}"
|
||||
fi
|
||||
|
||||
# Detect systemd-cat
|
||||
systemd_cat_path=""
|
||||
if command -v systemd-cat >/dev/null 2>&1; then
|
||||
systemd_cat_path=$(command -v systemd-cat)
|
||||
fi
|
||||
|
||||
# If user provided logfile explicitly, force file mode
|
||||
use_journal=false
|
||||
if [[ -n "${logfile}" ]]; then
|
||||
use_journal=false
|
||||
else
|
||||
if [[ -n "${systemd_cat_path}" ]]; then
|
||||
use_journal=true
|
||||
else
|
||||
use_journal=false
|
||||
fi
|
||||
fi
|
||||
|
||||
# Prepare logfile if needed
|
||||
mkdir -p -- "${logdir}"
|
||||
if ! $use_journal; then
|
||||
if [[ -z "${logfile}" ]]; then
|
||||
logfile="${logdir}/${cmd_basename}.${timestamp}.pid$$.log"
|
||||
fi
|
||||
# Ensure file exists and is writable
|
||||
: > "${logfile}" || { echo "Cannot write to log file: ${logfile}"; exit 1; }
|
||||
fi
|
||||
|
||||
# Helper: quote command for printing
|
||||
quoted_cmd() {
|
||||
local i out=""
|
||||
for i in "$@"; do
|
||||
printf -v i "%q" "$i"
|
||||
out="${out} ${i}"
|
||||
done
|
||||
printf '%s' "${out# }"
|
||||
}
|
||||
|
||||
# Build the inner script to run under setsid. We inject expanded variables from outer shell.
|
||||
if $use_journal; then
|
||||
# Compose systemd-cat args (escape tag and priority safely)
|
||||
# Note: we rely on simple token expansion; tag/priority are validated minimally below.
|
||||
journal_args=()
|
||||
journal_args+=( "-t" )
|
||||
journal_args+=( "$tag" )
|
||||
if [[ -n "$priority" ]]; then
|
||||
journal_args+=( "-p" )
|
||||
journal_args+=( "$priority" )
|
||||
fi
|
||||
|
||||
# Validate priority loosely (allow common names or numeric)
|
||||
case "$priority" in
|
||||
""|emerg|alert|crit|err|warning|notice|info|debug|0|1|2|3|4|5|6|7) ;;
|
||||
*)
|
||||
echo "Warning: unknown priority '$priority' — journald may reject it." >&2 ;;
|
||||
esac
|
||||
|
||||
# Prepare a single string of quoted journal args for insertion into the -c script
|
||||
# We need to protect values with single quotes if they contain special chars.
|
||||
journal_args_escaped=""
|
||||
for a in "${journal_args[@]}"; do
|
||||
# replace every single quote with '\'"\''
|
||||
a_escaped=${a//\'/\'"\'"\'}
|
||||
journal_args_escaped="$journal_args_escaped '$a_escaped'"
|
||||
done
|
||||
|
||||
inner_script=$(cat <<'EOF'
|
||||
umask __UMASK__
|
||||
cd / || true
|
||||
|
||||
# Close fds (best-effort)
|
||||
if [ -d /proc/self/fd ]; then
|
||||
for fdpath in /proc/self/fd/*; do
|
||||
fdnum=${fdpath##*/}
|
||||
case "$fdnum" in
|
||||
0|1|2) continue ;;
|
||||
esac
|
||||
eval "exec ${fdnum}>&-" 2>/dev/null || true
|
||||
done
|
||||
else
|
||||
maxfd=$(ulimit -n 2>/dev/null || echo 256)
|
||||
case "$maxfd" in (*[!0-9]*|"") maxfd=256 ;; esac
|
||||
fd=3
|
||||
while [ "$fd" -le "$maxfd" ]; do
|
||||
eval "exec ${fd}>&-" 2>/dev/null || true
|
||||
fd=$((fd+1))
|
||||
done
|
||||
fi
|
||||
|
||||
# Redirect stdio: stdin -> /dev/null, stdout+stderr -> systemd-cat (journal)
|
||||
exec </dev/null
|
||||
# Note: the systemd-cat command and its args are inserted by the outer script.
|
||||
exec > >( __SYSTEMD_CAT__ ) 2>&1
|
||||
|
||||
# Exec the target command; "$@" expands to the command and its args passed after --
|
||||
exec "$@"
|
||||
EOF
|
||||
ENV_ARGS=(
|
||||
--setenv=PATH="$PATH"
|
||||
--setenv=PWD="$PWD"
|
||||
)
|
||||
|
||||
# Substitute placeholders with safe values
|
||||
inner_script=${inner_script//'__UMASK__'/"$umask_val"}
|
||||
# Build the systemd-cat invocation string (path + args) — shell-escaped
|
||||
# We need a single token string like: /bin/systemd-cat -t 'tag' -p 'priority'
|
||||
systemd_cat_cmd="$(printf '%s' "$systemd_cat_path")$journal_args_escaped"
|
||||
# Replace placeholder __SYSTEMD_CAT__ with the built command
|
||||
inner_script=${inner_script//'__SYSTEMD_CAT__'/"$systemd_cat_cmd"}
|
||||
[ -n "$NVM_DIR" ] && ENV_ARGS+=(--setenv=NVM_DIR="$NVM_DIR")
|
||||
[ -n "$NVM_BIN" ] && ENV_ARGS+=(--setenv=NVM_BIN="$NVM_BIN")
|
||||
|
||||
# Start the detached process via setsid
|
||||
setsid bash -c "$inner_script" -- "${cmd[@]}" &
|
||||
else
|
||||
# Fallback: redirect to logfile (file mode)
|
||||
inner_script=$(cat <<'EOF'
|
||||
umask __UMASK__
|
||||
cd / || true
|
||||
systemd-run --user \
|
||||
"${ENV_ARGS[@]}" \
|
||||
--working-directory="$PWD" \
|
||||
--slice=StartProcess.slice \
|
||||
--unit="$UNIT_NAME" \
|
||||
--remain-after-exit \
|
||||
--collect \
|
||||
-- "$@"
|
||||
|
||||
# Close fds (best-effort)
|
||||
if [ -d /proc/self/fd ]; then
|
||||
for fdpath in /proc/self/fd/*; do
|
||||
fdnum=${fdpath##*/}
|
||||
case "$fdnum" in
|
||||
0|1|2) continue ;;
|
||||
esac
|
||||
eval "exec ${fdnum}>&-" 2>/dev/null || true
|
||||
done
|
||||
else
|
||||
maxfd=$(ulimit -n 2>/dev/null || echo 256)
|
||||
case "$maxfd" in (*[!0-9]*|"") maxfd=256 ;; esac
|
||||
fd=3
|
||||
while [ "$fd" -le "$maxfd" ]; do
|
||||
eval "exec ${fd}>&-" 2>/dev/null || true
|
||||
fd=$((fd+1))
|
||||
done
|
||||
fi
|
||||
|
||||
exec </dev/null
|
||||
exec > "__LOGFILE__" 2>&1
|
||||
|
||||
exec "$@"
|
||||
EOF
|
||||
)
|
||||
inner_script=${inner_script//'__UMASK__'/"$umask_val"}
|
||||
# Escape logfile path for safe insertion (single-quote style)
|
||||
log_escaped=${logfile//\'/\'"\'"\'}
|
||||
inner_script=${inner_script//'__LOGFILE__'/"'$log_escaped'"}
|
||||
setsid bash -c "$inner_script" -- "${cmd[@]}" &
|
||||
fi
|
||||
|
||||
child_pid=$!
|
||||
|
||||
# Try to disown if supported
|
||||
if command -v disown >/dev/null 2>&1; then
|
||||
disown "$child_pid" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Optionally write pidfile
|
||||
if [[ -n "${pidfile}" ]]; then
|
||||
mkdir -p -- "$(dirname "${pidfile}")"
|
||||
printf '%s\n' "${child_pid}" > "${pidfile}"
|
||||
fi
|
||||
|
||||
echo "Started command: $(quoted_cmd "${cmd[@]}")"
|
||||
echo "Script PID: $$"
|
||||
echo "Daemon PID: ${child_pid}"
|
||||
if $use_journal; then
|
||||
echo "Output destination: systemd-journald (via $(printf '%s' "$systemd_cat_path"))"
|
||||
echo "Journal tag: ${tag}"
|
||||
if [[ -n "${priority}" ]]; then
|
||||
echo "Journal priority: ${priority}"
|
||||
fi
|
||||
else
|
||||
echo "Log file: ${logfile}"
|
||||
fi
|
||||
if [[ -n "${pidfile}" ]]; then
|
||||
echo "PID file: ${pidfile}"
|
||||
fi
|
||||
echo "Started at: $(date --iso-8601=seconds 2>/dev/null || date +%Y-%m-%dT%H:%M:%S%z)"
|
||||
|
||||
if ! $use_journal; then
|
||||
echo
|
||||
echo "To follow the log: tail -F ${logfile}"
|
||||
else
|
||||
echo
|
||||
echo "To view logs for this tag: journalctl -t ${tag} -f"
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "📜 Logs : journalctl --user -u $UNIT_NAME -f"
|
||||
echo "✅ Manage : systemctl --user stop $UNIT_NAME"
|
||||
fi
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
> 个人并不打算无脑用`stow`,尤其不希望一些 systemd 服务和涉及 token 的自用小工具混进来。
|
||||
> 2. 还有一些早期配置在整理本仓库时已经淡忘,由于篇幅和复述可靠性有限,亦不考虑收纳。
|
||||
> 3. 涉及`$HOME`、`~`、`%h`开头(最后一个多见于 systemd 服务)的路径建议自行适配——我的设定你不一定会满意。
|
||||
> - 另注:gtklock 没有办法取巧,只能填绝对路径。算是为数不多的漏网之鱼。
|
||||
|
||||
## 鸣谢
|
||||
- 雪叶 [@Vescrity](https://github.com/Vescrity) (Yukitoha)
|
||||
@@ -19,7 +20,7 @@
|
||||
|-|-|-|
|
||||
|niri|`.config/niri/config*.kdl`|只拆分了`window-rule`和`binds`,拆太碎有些视觉效果会失效。|
|
||||
|`fuzzel`|`.config/fuzzel/*`|
|
||||
|`mako`|`.config/mako/*`|
|
||||
|`mako`|`.config/mako/*`|Chrome 的消息推送都是无脑标 CRITICAL 级,没有办法调持续时间,量一多还会卡在那里,只能`makoctl reload`强制重载。|
|
||||
|`swww`|`bin/chbg` (bash 脚本)|依赖`imagemagick`。另,可以配合图床等实现定期换壁纸。|
|
||||
|`gtklock`|`.config/gtklock/*`|现阶段无法跟`swayidle`合用,尽管其 Wiki 鼓励这么做。|
|
||||
|`xdg-desktop-portal-(gtk\|gnome)`|`.config/xdg-desktop-portal/*-portals.conf`|GNOME 支持最全,但称不上好看(|
|
||||
|
||||
Reference in New Issue
Block a user