replace ykrun with runbg for background command execution
... to solve the nvm-sh environment issue.(mostly vscode) NOTE: may also import other envvars, tbc.
This commit is contained in:
@@ -2,7 +2,7 @@ binds {
|
|||||||
Mod+F1 { show-hotkey-overlay; }
|
Mod+F1 { show-hotkey-overlay; }
|
||||||
|
|
||||||
Mod+Return hotkey-overlay-title="Terminal (foot)" { spawn "foot"; }
|
Mod+Return hotkey-overlay-title="Terminal (foot)" { spawn "foot"; }
|
||||||
Mod+F9 hotkey-overlay-title="Browser (chrome)" { spawn "ykrun" "google-chrome-stable"; }
|
Mod+F9 hotkey-overlay-title="Browser (chrome)" { spawn "google-chrome-stable"; }
|
||||||
Mod+E hotkey-overlay-title="Explorer (yazi)" { spawn "foot" "yazi"; }
|
Mod+E hotkey-overlay-title="Explorer (yazi)" { spawn "foot" "yazi"; }
|
||||||
//Shift+Mod+Return hotkey-overlay-title="Steam" { spawn "steam"; }
|
//Shift+Mod+Return hotkey-overlay-title="Steam" { spawn "steam"; }
|
||||||
|
|
||||||
|
|||||||
8
.zshrc
8
.zshrc
@@ -149,14 +149,6 @@ export GPG_TTY=$TTY
|
|||||||
|
|
||||||
alias noproxy='env -u http_proxy -u https_proxy'
|
alias noproxy='env -u http_proxy -u https_proxy'
|
||||||
|
|
||||||
alias ykls='systemctl --user status YukiLauncher.slice'
|
|
||||||
alias yksuspend='systemctl --user freeze YukiLauncher.slice'
|
|
||||||
alias ykcout='systemctl --user thaw YukiLauncher.slice'
|
|
||||||
alias ykexit='systemctl --user stop YukiLauncher.slice'
|
|
||||||
|
|
||||||
alias susp="systemctl --user freeze"
|
|
||||||
alias cont="systemctl --user thaw"
|
|
||||||
|
|
||||||
export NVM_DIR="$HOME/.nvm"
|
export NVM_DIR="$HOME/.nvm"
|
||||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
|
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
|
||||||
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
|
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
|
||||||
|
|||||||
@@ -12,4 +12,4 @@ for item in $(ls $desktop); do
|
|||||||
done
|
done
|
||||||
|
|
||||||
fsarg=$(echo -en "$options" | fuzzel --dmenu --prompt="Open Project with VSCode:")
|
fsarg=$(echo -en "$options" | fuzzel --dmenu --prompt="Open Project with VSCode:")
|
||||||
[ -z "$fsarg" ] || ykrun code "$desktop/$fsarg"
|
[ -z "$fsarg" ] || runbg -- code "$desktop/$fsarg"
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
option=$(fuzzel --dmenu --prompt-only="Command to execute: ")
|
option=$(fuzzel --dmenu --prompt-only="Command to execute: ")
|
||||||
[ -z "$option" ] || ykrun $option
|
[ -z "$option" ] || runbg -- $option
|
||||||
|
|||||||
210
bin/runbg
Executable file
210
bin/runbg
Executable file
@@ -0,0 +1,210 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#systemd-run --user --scope --slice=YukiLauncher.slice --unit="$1-$$".scope /bin/sh -c '"$@"' _ "$@"
|
||||||
|
|
||||||
|
# goddamn nvm-sh !!!
|
||||||
|
# have to update PATH before launch
|
||||||
|
PATH=$(zsh -c -i 'echo $PATH')
|
||||||
|
export PATH
|
||||||
|
|
||||||
|
# start-bg.sh - robustly start a command in the background and redirect stdout+stderr to a log
|
||||||
|
# Generated by GitHub Copilot.
|
||||||
|
|
||||||
|
# Features:
|
||||||
|
# - Uses setsid (preferred) to detach from the controlling terminal.
|
||||||
|
# - Falls back to nohup if setsid is unavailable.
|
||||||
|
# - Runs the command with stdin closed, stdout+stderr redirected to a logfile.
|
||||||
|
# - Sets a safe umask and changes to / to avoid blocking filesystems.
|
||||||
|
# - Writes a pidfile next to the log for easy management.
|
||||||
|
# - Uses positional args ($@), script PID ($$) and reports child PID ($!).
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# start-bg.sh [ -l LOGFILE | -d LOGDIR ] [ -m METHOD ] -- command [args...]
|
||||||
|
#
|
||||||
|
# Options:
|
||||||
|
# -l, --log LOGFILE Path to log file (if omitted an auto name is used)
|
||||||
|
# -d, --dir LOGDIR Directory for autogenerated logs (default: ./logs)
|
||||||
|
# -m, --method METHOD Background method: setsid (default) | nohup
|
||||||
|
# -h, --help Show this help and exit
|
||||||
|
#
|
||||||
|
# Examples:
|
||||||
|
# ./start-bg.sh -- sleep 60
|
||||||
|
# ./start-bg.sh -d /var/log/myapp -- /usr/bin/myapp --config /etc/myapp.conf
|
||||||
|
# ./start-bg.sh -l ./my.log -- /usr/bin/myapp arg1 arg2
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
progname=$(basename "$0")
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<EOF
|
||||||
|
Usage: $progname [ -l LOGFILE | -d LOGDIR ] [ -m METHOD ] -- command [args...]
|
||||||
|
|
||||||
|
Start "command [args...]" detached from the terminal and redirect stdout+stderr to a log.
|
||||||
|
|
||||||
|
METHOD:
|
||||||
|
setsid - use setsid to start a session and detach (preferred)
|
||||||
|
nohup - use nohup (fallback/compat)
|
||||||
|
|
||||||
|
When no -l is provided, a log file is auto-generated:
|
||||||
|
<LOGDIR>/<command>.<YYYYMMDD-HHMMSS>.pid<$$>.log
|
||||||
|
|
||||||
|
A pidfile is written as <logfile>.pid containing the child PID.
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Defaults
|
||||||
|
logdir="/tmp/$USER/runner"
|
||||||
|
logfile=""
|
||||||
|
method="setsid"
|
||||||
|
|
||||||
|
# Parse options until the `--` separator
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
-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 ;;
|
||||||
|
-m|--method)
|
||||||
|
if [[ $# -lt 2 ]]; then echo "Missing argument for $1"; usage; fi
|
||||||
|
method="$2"; shift 2 ;;
|
||||||
|
-h|--help)
|
||||||
|
usage ;;
|
||||||
|
--)
|
||||||
|
shift; break ;;
|
||||||
|
-*)
|
||||||
|
echo "Unknown option: $1"; usage ;;
|
||||||
|
*)
|
||||||
|
break ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Remaining args are the command to run
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
echo "Error: no command specified."
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Preserve the command and args
|
||||||
|
cmd=( "$@" )
|
||||||
|
cmd_basename=$(basename "${cmd[0]}")
|
||||||
|
timestamp=$(date +%Y%m%d-%H%M%S)
|
||||||
|
|
||||||
|
mkdir -p -- "${logdir}"
|
||||||
|
|
||||||
|
if [[ -z "${logfile}" ]]; then
|
||||||
|
logfile="${logdir}/${cmd_basename}.${timestamp}.pid$$.log"
|
||||||
|
fi
|
||||||
|
|
||||||
|
pidfile="${logfile}.pid"
|
||||||
|
|
||||||
|
# Validate method
|
||||||
|
case "${method}" in
|
||||||
|
setsid|nohup) ;;
|
||||||
|
*)
|
||||||
|
echo "Invalid method: ${method}. Allowed: setsid|nohup"
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Prepare environment for child
|
||||||
|
# We construct a small wrapper for safe daemonization:
|
||||||
|
start_with_setsid() {
|
||||||
|
# Prefer existing setsid binary (coreutils/util-linux)
|
||||||
|
if ! command -v setsid >/dev/null 2>&1; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Use setsid to start the process in a new session. We:
|
||||||
|
# - set a conservative umask
|
||||||
|
# - change to / to avoid keeping directories busy
|
||||||
|
# - close stdin and redirect stdout/stderr to logfile
|
||||||
|
#
|
||||||
|
# We run setsid directly with the command array so arguments are preserved.
|
||||||
|
#
|
||||||
|
# Note: redirecting >"$logfile" 2>&1 < /dev/null outside ensures the setsid child
|
||||||
|
# inherits the redirections.
|
||||||
|
(
|
||||||
|
umask 022
|
||||||
|
cd / || true
|
||||||
|
# exec will replace the subshell with the command
|
||||||
|
exec "${cmd[@]}"
|
||||||
|
) >"${logfile}" 2>&1 < /dev/null &
|
||||||
|
child_pid=$!
|
||||||
|
|
||||||
|
# Detach the job from this shell's job table if possible
|
||||||
|
disown "$child_pid" 2>/dev/null || true
|
||||||
|
|
||||||
|
# setsid the already-forked child to start a new session. Some systems allow:
|
||||||
|
# setsid -w <pid>
|
||||||
|
# but that's nonportable; instead we try to re-exec the command under setsid.
|
||||||
|
# If `setsid` can't be applied to the backgrounded PID, we respawn via setsid:
|
||||||
|
if setsid true >/dev/null 2>&1; then
|
||||||
|
# Respawn under setsid to ensure proper session leader if available.
|
||||||
|
# Kill the previous child (it is still running) and restart under setsid.
|
||||||
|
# To avoid races: only do this if cmd is still running and the pid we started is a shell wrapper.
|
||||||
|
if kill -0 "$child_pid" 2>/dev/null; then
|
||||||
|
# Attempt to terminate wrapper and spawn a true setsid child.
|
||||||
|
kill "$child_pid" 2>/dev/null || true
|
||||||
|
# Short sleep to allow process cleanup (best-effort)
|
||||||
|
sleep 0.05
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Now start the real setsid-backed child with same redirections
|
||||||
|
setsid "${cmd[@]}" >"${logfile}" 2>&1 < /dev/null &
|
||||||
|
child_pid=$!
|
||||||
|
disown "$child_pid" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '%s' "$child_pid"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
start_with_nohup() {
|
||||||
|
# Use nohup as fallback; nohup will ignore HUP but doesn't start a new session.
|
||||||
|
nohup "${cmd[@]}" >"${logfile}" 2>&1 < /dev/null &
|
||||||
|
child_pid=$!
|
||||||
|
disown "$child_pid" 2>/dev/null || true
|
||||||
|
printf '%s' "$child_pid"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main launcher: pick method and start
|
||||||
|
echo "Launching command: ${cmd[*]}"
|
||||||
|
echo "Log file: ${logfile}"
|
||||||
|
echo "Method: ${method}"
|
||||||
|
|
||||||
|
child_pid=""
|
||||||
|
|
||||||
|
if [[ "${method}" == "setsid" ]]; then
|
||||||
|
# Try to start via setsid; if setsid not present, fallback to nohup
|
||||||
|
if child_pid=$(start_with_setsid); then
|
||||||
|
: # success
|
||||||
|
else
|
||||||
|
echo "setsid not available, falling back to nohup"
|
||||||
|
child_pid=$(start_with_nohup)
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
child_pid=$(start_with_nohup)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Write pidfile (best-effort)
|
||||||
|
if [[ -n "${child_pid}" ]]; then
|
||||||
|
printf '%s\n' "${child_pid}" > "${pidfile}" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Reporting
|
||||||
|
echo "Script PID: $$"
|
||||||
|
if [[ -n "${child_pid}" ]]; then
|
||||||
|
echo "Child PID: ${child_pid}"
|
||||||
|
else
|
||||||
|
echo "Child PID: (unknown)"
|
||||||
|
fi
|
||||||
|
echo "Pidfile: ${pidfile}"
|
||||||
|
echo "Started at: $(date --iso-8601=seconds 2>/dev/null || date +%Y-%m-%dT%H:%M:%S%z)"
|
||||||
|
echo
|
||||||
|
echo "To follow the log: tail -F ${logfile}"
|
||||||
|
|
||||||
|
exit 0
|
||||||
Reference in New Issue
Block a user