#!/usr/bin/env sh # YES_ZSH stfu() { ### @- ### invoke a command, silencing stdout and stderr *unless* the command fails. ### ### **NOTE:** don't use `stfu` for handling sensitive data or commands! ### use it for 7zip. ### ### ``` ### $ touch butts ### $ stfu 7z a butts.7z butts ### $ stfu 7z a butts.7z asses ### command failed with exit status 1: ### 7z a butts.7z asses ### ### $ tail -n 20 /tmp/stfu/out_1627834220 ### Solid = - ### Blocks = 0 ### ### Scanning the drive: ### 0 files, 0 bytes ### ### Updating archive: butts.7z ### ### Keep old data in archive: 1 file, 0 bytes ### Add new data to archive: 0 files, 0 bytes ### ### ### Files read from disk: 0 ### Archive size: 82 bytes (1 KiB) ### ### Scan WARNINGS for files and folders: ### ### asses : The system cannot find the file specified. ### ---------------- ### Scan WARNINGS: 1 ### ### $ tail -n 20 /tmp/stfu/err_1627834220 ### ### WARNING: The system cannot find the file specified. ### asses ### ``` [ $# -gt 0 ] || { printf "%s\n" "$0: too few arguments" >&2; return 1; } local dirty=0 temp="$STFU_DIR" if [ -z "$temp" ]; then temp="$(mktemp -dt stfu.XXXXXXXXXX)" [ $? -eq 0 ] || { printf "%s\n" "$0: failed create temporary directory" >&2; return 1; } dirty=1 fi # NOTE: this stat command will not work on BSD-likes, # but it will work with GNU coreutils and busybox. local perms="$(stat -c '%a' "$temp")" local realtemp="$(readlink -f "$temp")" [ -z "$MSYSTEM" ] || perms=700 # MSYS2 is insecure, oh well. if [ -d "$temp" ] && [ "$realtemp" = "$temp" ] && [ "$perms" = 700 ]; then if [ $dirty -ne 0 ]; then export STFU_DIR="$temp" fi else if [ -n "$STFU_DIR" ]; then printf "%s\n" "$0: invalid temporary directory, please unset STFU_DIR" >&2; else printf "%s\n" "$0: something went horribly wrong, maybe you can tell?" "$perms" "$realtemp" fi return 1 fi local time="$(date -u '+%s')" [ $? -eq 0 ] || { printf "%s\n" "$0: failed to get current time" >&2; return 1; } mkdir -p "$temp" || { printf "%s\n" "$0: failed to create temp directory" >&2; return 1; } while [ -e "$temp/out_$time" -o -e "$temp/err_$time" ]; do time=$((time+1)); done local out="$temp/out_$time" local err="$temp/err_$time" touch "$out" && touch "$err" || { printf "%s\n" "$0: failed to create temp files" >&2; return 1; } #local out="$(mktemp -t -p "$temp" out_XXXXXX)" #[ $? -eq 0 ] || { printf "%s\n" "$0: failed to create temp file" >&2; return 1; } #local err="$(mktemp -t -p "$temp" err_XXXXXX)" #[ $? -eq 0 ] || { printf "%s\n" "$0: failed to create temp file" >&2; return 1; } local ret=0 "$@" > "$out" 2> "$err" || ret=$? if [ $ret -ne 0 ]; then printf "command failed with exit status %s:\n" $ret >&2 echo2 "$@" echo2 note '$ tail -n 20' "$out" tail -n 20 "$out" >&2 echo2 note '$ tail -n 20' "$err" tail -n 20 "$err" >&2 fi return $ret } preload() { local preload='set -- $@'; while [ $# -gt 0 ]; do . ~/sh/$1 || exit 2; shift; done; } eval ${preload:-preload} echo2 note [ -n "${preload+-}" ] || stfu "$@"