|
|
|
|
|
by gaigalas
29 days ago
|
|
Here's how I deal with it using feature detection: case "$({
printf %b "\\061" ||
print -r -- 2 ||
echo -n -e "\\063" ||
command -p printf %b "\\064"; } 2>/dev/null)"
in
1)
alias _printb1='printf %b'
alias _printn1='printf %s'
;;
2)
alias _printb1='print -n --'
alias _printn1='print -nr --'
;;
3)
alias _printb1='echo -n -e'
alias _printn1='echo -n -E'
;;
4)
_printb1 () { command -p printf '%b' "$1"; }
_printn1 () { command -p printf '%s' "$1"; }
;;
'-e 3')
_pdash () { _pd=$1; while :; do case $_pd in -*) echo -n "\\055"; _pd=${_pd#-};; *) break;; esac; done; }
_printb1 () { _pdash "$1"; echo -n "$_pd"; }
_printn1 () {
local _p _r
_pdash "$1"; _r=$_pd
while case $_r in *"$_BS"*) :;; *) false;; esac; do
_p=${_r%%"$_BS"*}
_r=${_r#*"$_BS"}
echo -n "$_p$_BS$_BS"
done
_pdash "$_r"; _r=$_pd
echo -n "$_r"
}
;;
*)
exit 1;;
esac
1) is for shells who have printf, 2) is for the ksh family, 4) is for PATH='' yash exclusively, -e 3) is for posh exclusively.It exports two callables, _printb1 and _printf1 that escape and don't escape backslashes respectively, are immune to trailing dash gotchas and other pitfalls. Unfortunatelly, not all shells allow overriding `echo` so I can't proper polyfill when necessary. I'm going to extremes here, but a simpler version of this can be used for the most popular shells. |
|
But it does feel complex to me.
Personally I just write in the common subset of bash and OSH, which is very large. I never need to support say dash, since every machine that has dash also has bash, which is less broken in terms of 'echo' and so forth.
bash has its own broken-ness, but running under OSH solves that.
And OSH also supports some busybox idioms -- we learned last year that bash cannot run busybox ash scripts on Alpine
e.g. 'chdir' is an alias for 'cd' in busybox, but not in bash. And Alpine scripts use it, so bash can't run Alpine scripts, but OSH can (as of last year).