Назад | Перейти на главную страницу

Почему эта футболка теряет стандартный вывод?

Простой скрипт:

#!/bin/bash
remote_ssh_account="depesz@localhost"
directory_to_tar=pgdata
exec nice tar cf - "$directory_to_tar" | \
    tee >(
        md5sum - | \
        ssh "$remote_ssh_account" 'cat - > /tmp/h3po4-MD5-2012-03-13.tar'
    ) | \
    ssh "$remote_ssh_account" 'cat - > /tmp/h3po4-data-2012-03-13.tar'

Теоретически он должен доставить данные и контрольную сумму на удаленную машину.

Но почему-то у тройника не получается:

tee: standard output: Resource temporarily unavailable

Сделал strace, но ничего не вышло. Я вижу, как запущен ssh, и tee записывает в оба из них, но только канал (md5sum | ssh) получает данные - strace ssh "data" не получает никаких данных, и через 5 секунд tee показывает ошибку.

Помимо этого все работает. Установлено 2 подключения, работает tar, работает md5sum и его доставка.

Обнаружена проблема. Вот соответствующая часть strace:

[pid 10243] write(1, "pFl\r\347\345]\244Hi\336\253,-\231\247\344\234\241\332\302\252\315\243G\234\225+\241\323\316s"..., 4096 <unfinished ...>
[pid 10247] select(7, [3 4], [3], NULL, {10, 0} <unfinished ...>
[pid 10243] <... write resumed> )       = -1 EAGAIN (Resource temporarily unavailable)
[pid 10247] <... select resumed> )      = 1 (out [3], left {10, 0})
[pid 10243] write(2, "tee: ", 5tee:  <unfinished ...>
(...)
[pid 10243] write(2, "standard output", 15standard output <unfinished ...>
(...)
[pid 10243] write(2, ": Resource temporarily unavailab"..., 34: Resource temporarily unavailable) = 34

Итак, что происходит, удаленный ssh ​​еще не готов для продолжения записи. Большинство программ справляются с этим правильно, но Ти решает умереть в кучу. Видеть http://lists.freebsd.org/pipermail/freebsd-bugs/2012-Feb February/047528.html за одну ссылку на такого рода поведение. Есть еще пара, которую я нашел в кратком поиске "EAGAIN tee".

Решение, которое нашел lhunath, работает, потому что оно заставляет bash обрабатывать EAGAIN. Элегантный.

Попробуйте это, альтернативный способ сделать разрыв трубы:

#!/bin/bash
remote_ssh_account="depesz@localhost"
directory_to_tar=pgdata
nice tar cf - "$directory_to_tar" | \
    tee >(
        md5sum | \
        ssh "$remote_ssh_account" 'cat > /tmp/h3po4-MD5-2012-03-13.sum'
    ) > >(
        ssh "$remote_ssh_account" 'cat > /tmp/h3po4-data-2012-03-13.tar'
    )