> I’ll quote Rich’s sh (POSIX shell) tricks to end this:
> I am a strong believer that Bourne-derived languages are extremely bad, on the same order of badness as Perl, for programming, and consider programming sh for any purpose other than as a super-portable, lowest-common-denominator platform for build or bootstrap scripts and the like, as an extremely misguided endeavor
split-on-ddash outputa outputb a b c -- x y z
for x in "${outputa[@]}"; do # ...
becomes feasible. Of course, don't do it.I have tried Bash namerefs. I found them to be kinda awkward, since you need to name them uniquely. So, you have to pretend that they are global variables, even though they are declared inside a function, which makes their usage verbose.
Here, this could look like:
split_by_double_dash() {
declare -n split_by_double_dash_before=$1
declare -n split_by_double_dash_after=$2
split_by_double_dash_before=()
split_by_double_dash_after=()
...
}
split-by-double-dash a b c -- d e f should return the lists [a, b, c] and [d, e, f]
FWIW in YSH (https://oils.pub/ysh.html), you can do this in a style that's like Python and JavaScript, but you can also combine it with shell idioms.
First create it and pretty print it:
ysh-0.34$ var li = :| a b c -- d e f | # shell word style, ['a', 'b'] style is also accepted
ysh-0.34$ = li # pretty print with =
(List) ['a', 'b', 'c', '--', 'd', 'e', 'f']
Then test out the indexOf() method on strings: ysh-0.34$ = li.indexOf('--')
(Int) 3
Then write the function: ysh-0.34$ func splitBy(li) {
> var i = li.indexOf('--')
> assert [i !== -1]
> return ( [li[ : i], li[i+1 : ]] ) # same slicing as Python
> }
Call it and unpack it ysh-0.34$ var front, back = splitBy(li)
ysh-0.34$ = front
(List) ['a', 'b', 'c']
Use it in shell argv, with @myarray as splicing: ysh-0.34$ write -- @back
d
e
f
(I guess we're duplicating threads at this point :D)
if .["found"] then
. | .after += [$arg]
elif $arg == "--" then
. | .found = true
else
. | .before += [$arg]
end
or for (i = $indicies) if { ~ $*($i) -- } {
before = <= {
...
...is more readable and maintainable than: my ($before, $after) = split /\s*--\s*/, $input;
my @list1 = split ' ', $before;
...
jeffrallen•4h ago
Do not fall into the trap of big complex shell scripts.
zhouzhao•3h ago
This so much.
SoftTalker•3h ago
Systems admins are generally not Python or Go experts. And those are two dependencies which may not be available anyway (or will require installation, and maintenancee, may introduce new vulns, etc.). You could say the same about 'jq' though.
calmbonsai•1h ago
Shell is great for personal or local-group/team automation, but outside of a bootstrap, it should _never_ be used for anything in deployed production.
The 3 main issues are hidden deps, error handling, and performance.