Jeff King <peff@xxxxxxxx> writes: > The packetize() function takes its input on stdin, and requires 4 > separate sub-processes to format a simple string. We can do much better > by getting the length via the shell's "${#packet}" construct. The one > caveat is that the shell can't put a NUL into a variable, so we'll have > to continue to provide the stdin form for a few calls. Yuck. Binary protocol and shell variables do not mix well. Documentation/CodingGuidelines forbids ${#parameter} in the first place and we seem to use it only when we know we are using bash. Perhaps we should start considering to lift it. I dunno. > +# convert function arguments or stdin (if not arguments given) to pktline > +# representation. If multiple arguments are given, they are separated by > +# whitespace and put in a single packet. Note that data containing NULs must be > +# given on stdin, and that empty input becomes an empty packet, not a flush > +# packet (for that you can just print 0000 yourself). > packetize() { > + if test $# -gt 0 > + then > + packet="$*" > + printf '%04x%s' "$((4 + ${#packet}))" "$packet" This allows packetize "want $hash_head" to be written like so: packetize want "$hash_head" which maybe is a handy thing to do. > + else > + cat >packetize.tmp && > + len=$(wc -c <packetize.tmp) && > + printf '%04x' "$(($len + 4))" && > + cat packetize.tmp && > + rm -f packetize.tmp perl -e ' my $data = do { local $?; <STDIN> }; printf "%04x%s", length($data), $data; ' That's one process but much heavier than cat/wc/printf/cat, I guess. > + fi > } > > # Parse the input as a series of pktlines, writing the result to stdout.