#!/usr/bin/env sh # compat: +ash +bash +dash -hush -ksh +mksh +oksh +osh +posh +yash +zsh __maybesudo() { ### @maybesudo ### mimic certain features of `sudo` for systems without it installed. ### as it stands, this mostly just handles some environment variables. ### ### try this: `maybesudo -u "$USER" printenv` complain() { printf >&2 'maybesudo: %s\n' "$*" } usage() { printf %s\\n \ 'maybesudo - a dumb utility for systems without sudo' \ '' \ 'usage: maybesudo -h | -V' \ 'usage: maybesudo [-u user] command [arg ...]' \ 'usage: maybesudo [-u user] file ...' \ ; } name= env_cleanup=0 while getopts :AEHKPSVbhiklnsvC:U:g:p:r:t:u: name; do case "$name" in ([KVk]) # K: sure kill # V: version # k: kill complain 'your system does not have sudo installed!' return 0 ;; (h) usage return 0 ;; ([AEHPSnp]) # A: askpass # E: preserve environment # H: HOME # P: preserve group vector # S: stdin (password) # n: non-interactive # p: prompt complain 'option has no effect --' "'$name'" ;; ([CUbgilrstv]) # C: close from (fd) # U: other user (in conjunction with -l) # b: background # g: group # i: simulate initial login (TODO) # l: list # r: role (SELinux) # s: shell (TODO) # t: type (SELinux) # v: validate complain 'unsupported option --' "'$name'" return 1 ;; (u) # user if [ -z "$USER" ] || [ "$OPTARG" != "$USER" ]; then complain 'users other than yourself are unsupported!' return 1 fi env_cleanup=1 ;; (:) complain 'option requires an argument --' "'$OPTARG'" return 1 ;; (*) complain 'invalid option --' "'$OPTARG'" return 1 ;; esac done shift "$((OPTIND-1))" if [ $# = 0 ]; then usage >&2 exit 64 # EX_USAGE fi if [ "$env_cleanup" = 1 ]; then # portably listing exported variable names is virtually impossible # without the blessing of null-terminated strings, so don't even try. # just export the bare minimum that a fairly stock sudo would. # TODO: you know, awk has an ENVIRON array that might be easier to work with. # don't eat up precious command space with dumb colors. # xargs --show-limits says: # Maximum length of command we could actually use: 5080 [ "${#LS_COLORS}" -le 1024 ] || LS_COLORS= # doas seems to override PATH with /bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin # sudo also sets SUDO_COMMAND, SUDO_GID, SUDO_UID, SUDO_USER, and MAIL, # but who needs those? # "${USER:+DOAS_USER=}${USER}" # "${USER:+SUDO_USER=}${USER}" # "${LOGNAME:+LOGNAME=}${USER:--i}" [ -z "$XAUTHORIZATION" ] || set -- XAUTHORIZATION="$XAUTHORIZATION" "$@" [ -z "$XAUTHORITY" ] || set -- XAUTHORITY="$XAUTHORITY" "$@" [ -z "$USERNAME" ] || set -- USERNAME="$USERNAME" "$@" [ -z "$USER" ] || set -- USER="$USER" "$@" [ -z "$TERM" ] || set -- TERM="$TERM" "$@" [ -z "$SHELL" ] || set -- SHELL="$SHELL" "$@" [ -z "$PATH" ] || set -- PATH="$PATH" "$@" [ -z "$LS_COLORS" ] || set -- LS_COLORS="$LS_COLORS" "$@" [ -z "$KRB5CCNAME" ] || set -- KRB5CCNAME="$KRB5CCNAME" "$@" [ -z "$HOSTNAME" ] || set -- HOSTNAME="$HOSTNAME" "$@" [ -z "$HOME" ] || set -- HOME="$HOME" "$@" [ -z "$DPKG_COLORS" ] || set -- DPKG_COLORS="$DPKG_COLORS" "$@" [ -z "$DISPLAY" ] || set -- DISPLAY="$DISPLAY" "$@" [ -z "$COLORS" ] || set -- COLORS="$COLORS" "$@" set -- -i "$@" elif ! [ -d /C ]; then # no such thing as sudo on Windows (kinda) complain 'you requested root permissions, but you do not have sudo installed.' return 69 # EX_UNAVAILABLE fi exec env "$@" } maybesudo_()(__maybesudo "$@") # deprecated [ -n "${preload+-}" ] || . ~/sh/preload || exit 2 eval ${preload:-preload} has if has sudo; then maybesudo() { sudo "$@"; } elif has doas; then maybesudo() { doas "$@"; } else maybesudo() (__maybesudo "$@") fi [ -n "${preload+-}" ] || __maybesudo "$@"