Недавно локализовал баг. При определенных методах записи в $acpi_dir/brightness слишком частые записи приводят к ошибке "invalid argument". Это происходит если запись идет через "cat > $acpi_dir/brightness", замена "cat" на чепуху типа tr ' ' ' ' или "tee > ..." бесполезна. А вот bc этому не подвержен, и так как на входе цифры, то он отлично справляется с ролью cat. Но это скорее заглушка.
Можно пережить sigpipe если не игнорировать результат записи. Минимальный пример:
Shell
n=1
while :; do
echo $n
n=$(( (n + 10) % 2000 ))
sleep 0.001
done | stdbuf -oL awk 'BEGIN {
cmd = "exec cat > /sys/class/backlight/intel_backlight/brightness"
PROCINFO[cmd, "NONFATAL"]=1
}{
ERRNO=0
print ($1+2000) | cmd
if (ERRNO) {
print (ERRNO, $1 + 2000) > "/dev/stderr"
close (cmd)
}
}'
Если же запись идет прямо в файл, а не через посредника типа cat, то можно вообще избежать sigpipe, если делать fflush().
Код: Выделить всё
ERRNO=0
print ($1+2000) > acpi_file
if (ERRNO) {
print (ERRNO, $1 + 2000) > "/dev/stderr"
close (acpi_file)
} else {
fflush (acpi_file);
}
А вот пример с awk, работающим на своей частоте (более высокой). Правда все, что в @load 'time' считается устаревшим, взамен рекомендуют самим ставить timex из своей коллекции (интересно, если в дистрах пакеты типа awk-plugin-* или awk-plugins[куча юзов]).
Shell
n=1
while :; do
echo $n
n=$(( (n + 1) % 10 ))
sleep 1
done | awk '
@load "time"
BEGIN {
PROCINFO["/dev/stdin", "READ_TIMEOUT"] = 1000/30
PROCINFO["/dev/stdin", "RETRY"] = 1
while (1) {
t = gettimeofday()
switch (getline < "/dev/stdin") {
case 1: print $1;
case 0: break;
default: printf "."
}
sleep(1/30)
}
}'