tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Shell Command Substitution and fork()



EF> Unsurprisingly, [ast-ksh] doesn't fork.
EF> Does anyone know how those ksh's achieve that?
kre> I haven't look at their sources, but I would assume they don't fork.
I concur. The most probable way to achieve non-forking is not to fork.

EF> Are there any drawbacks?    
kre> [ash] already has code to attempt to do that, but it doesn't currently
kre> work properly in all cases, so has been disabled (long ago).
So it's probably hard to get right.

To re-phrase my question: certain ksh's manage to perform thigs demanded to 
take place in a Subshell Environment without fork()ing, whereas all other 
shells known to me fork(). So I can think of three possibilities:
1. They are doing something extremely clever/ugly that only works in the 
context of ksh's foo-baz-something internals
2. They are doing something that mostly works, but has non-trivial issues, 
either violating POSIX or non-POSIX shell common sense.
3. They just got it right while no other shell has managed to do so.

I would hope for 3. so one could plug that code (or concept) into ash.

> Of course there is only a big speedup when the command is a shell builtin
Or a function.
Whereas, with a function, one could circumvent the problem by making the 
function assign the result to a global variable instead of printing it.

> [As I understand it, the issue is with correct cleanup, especially in the
> case of errors - nothing [i]n the sub-shell environ is allowed to affect
> the parent shell, so anything in the cmd-sub that changes anything at all
> has to be undone - fork() makes that simple to get right, exit() cleans
> up everything...]
Yes, of course.

> that's what command substitution is for after all
Yes. But although X is for Y after all, Z may as well achieve Y. I always 
like to learn new shell trickery.

> But in some cases, depending upon exactly what the printf is doing,
> there can be other ways.
Yes, please?

I'm generally interested in the subject, but the code in question here does 
IPv6 address mangling: normalizing to X::Y form, combining (base address, 
prefix length, relative address) triples into an address and the like. 
The printf's are like
	printf "%02X%02X:%02X%02X" "$@"
or
	printf "%04X" 0x"$xyz"
or
	printf "%0$(( 33 - ${#xyz} ))X" 0
or
	printf "%x" 0x"$(printf "%.4s" "${xyz}")"
or
	printf "%.$(($2 / 4))s%s\n" "$1" "${3#$(printf "%.$(($2 / 4))s" "$3")}"
(Yes, that's all part of real, working, tested code I wrote. I do declare 
it would take me some sec^Wmin^Wwhatever to re-understand it.)


Home | Main Index | Thread Index | Old Index