Some testcases for concurrent background jobs and pipe I/O
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
a: 1 2 1 2 1 1 2 1 2 1 2 1 2 1 2 1 2 1 1 2 1 2 1 2 1 2 1 2 1 2 1=16 2=14 | |
b: 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 2 1 2 1 2 1 2 1 2 1 2 1 2 1=14 2=16 | |
c: 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 1=15 2=15 | |
d: 2 1 1 2 1 2 1 1 2 1 2 1 2 1 1 2 1 1 2 1 2 1 1 2 1 2 1 1 2 1 1=18 2=12 | |
e: 3 2 3 2 3 2 3 2 3 2 3 2 3 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 3 2 2=14 3=16 | |
f: 2 2 1 2 1 2 1 2 1 2 2 1 2 1 2 1 1 2 1 2 1 2 2 1 2 1 2 1 2 1 1=14 2=16 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
function compatFixes { | |
${BASH_VERSION+shopt -s extglob lastpipe} | |
if [[ ${!KSH_VERSION} == .sh.version ]]; then | |
function read { | |
command read "${@/#*(-[^a])a*(?)/\1A\2}" | |
} | |
fi | |
} | |
# Functions share a stream of zeros. | |
function zeros { | |
printf '%.s0' {1..30} | |
} | |
# Reader function. | |
function z { | |
typeset -li x= | |
while IFS= read -rN1 _; do | |
((x++)) | |
printf %-2d "$1" # keep track of which job this is. | |
done | |
} | |
# read, format, print output from z jobs | |
function out { | |
typeset -lia totals=() zs=() | |
read -ra zs | |
printf %-2s "${zs[@]}" | |
typeset -li x= | |
for x in "${zs[@]}"; do | |
((totals[x]++)) | |
done | |
printf %s "${clrs[green]}" | |
for x in "${!totals[@]}"; do | |
printf '%s=%s ' "$x" "${totals[x]}" | |
done | |
printf '%s\n' "${clrs[reset]}" | |
} | |
### example funcs ### | |
# For some reason Bash doesn't require an explicit <&0 in this case. | |
function a { | |
out < <({ z 1 & z 2; } < <(zeros)) | |
} | |
# As above, with piped output. | |
function b { | |
{ z 1 <&0 & z 2; } < <(zeros) | out | |
} | |
# Same as b. | |
function c { | |
zeros | { z 1 <&0 & z 2; } | out | |
} | |
# Like the above two. Redirect to each z individually. Now behaves as the first example again. | |
function d { | |
typeset x | |
{ z 1 <&$x & z 2 <&$x; } {x}< <(zeros) | out | |
} | |
# The first command in the list to be explicitly redirected to the proper input, | |
# and all subsequent members, are asynchronous as expected. | |
function e { | |
typeset x | |
{ z 1 & z 2 <&$x & z 3 & } {x}< <(zeros) <&$x | out | |
} | |
# Pass the name of the pipe to g and individually redirect to z. Doesn't work. | |
# Pipe is closed before the second call to f sees it: | |
function f { | |
function g { z 1 & z 2; } <"$1" | |
g <(zeros) | out | |
unset -f g | |
} | |
function main { | |
compatFixes | |
typeset -A clrs=( | |
[green]="$(tput setaf 2)" | |
[reset]="$(tput sgr0)" | |
) | |
typeset fn | |
for fn; do | |
printf '%s: ' "$fn" | |
"$fn" | |
done | |
} | |
main {a..f} | |
# vim: set fenc=utf-8 ff=unix ts=4 sts=4 sw=4 ft=sh et: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment