; env [name=value]... [utility [argument...]]: with no utility, the ; exported variables (and those given) as name=value lines; with one, it ; runs with those set and exported for it alone, the input handed on, its ; output and status as its own. -i (an empty environment) is not here: the ; shell's HOME, PWD and USER are always seen. (def usage "usage: env [name=value]... [utility [argument...]]") (def assignment (re-compile "^[A-Za-z_][A-Za-z0-9_]*=")) ; the leading name=value words, then the rest (def split (fn (args) (letv (sets rest) (iterate (fn (st) (letv (sets rest) st (if (or (= (length rest) 0) (is-nil (re-match assignment (nth rest 0)))) (list) (let ((w (nth rest 0)) (eq (byte-find (nth rest 0) "="))) (tuple (list-append sets (tuple (byte-sub w 0 eq) (byte-sub w (+ eq 1)))) (tail rest)))))) (tuple (list) args)) (tuple sets rest)))) (def merged (fn (env sets) (let ((given (map (fn (s) (letv (n v) s n)) sets))) (list-concat (filter (fn (e) (letv (n v) e (= (length (filter (fn (g) (= g n)) given)) 0))) env) sets)))) (cond ((and (> (length ARGS) 0) (= (byte-sub (nth ARGS 0) 0 1) "-") (not (= (nth ARGS 0) "--"))) (do (err-write "env: " (nth ARGS 0) " is not supported here\n" usage "\n") (exit-status 125))) (else (letv (sets rest) (split (if (and (> (length ARGS) 0) (= (nth ARGS 0) "--")) (tail ARGS) ARGS)) (if (= (length rest) 0) (map (fn (e) (letv (n v) e (out-write n "=" v "\n"))) (merged (env-list) sets)) (letv (st o e) (run rest (in-read) sets) (do (out-write o) (err-write e) (exit-status st)))))))