Вопрос: Почему этот тей проигрывает?


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

#!/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) получает данные из ssh «данных», не получает никаких данных, и через 5 секунд tee показывает ошибку.

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


6
2018-03-14 19:21


Источник


На strace фронт, попробуйте strace -fF, Работает как чемпион для меня. - BMDan
-fF не в ручном режиме, но есть -f, -F и -ff. я использовал strace -ff -o strace.log -s 512 ./z.sh
-fF такой же как -f -F, -F на самом деле не задействован в большинстве систем, над которыми я работаю, но он (пытается) следовать vforks на более старых версиях strace и не влияет на более новые, но это не повредит. -ff заканчивается написанием кучи файлов (по одному на PID), которые затем вам нужно собрать обратно в разумную временную шкалу, поэтому я избегаю этого в подавляющем большинстве ситуаций. Тем не менее, -ff должен работать, но выходные файлы будут странно названы. - BMDan


Ответы:


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

#!/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'
    )

3
2018-03-14 19:50



Кажется, работает. Мне все еще хотелось бы знать, почему | ssh вещь ломается.


Обнаружена проблема. Вот соответствующая часть 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-February/047528.html для одной ссылки на такого рода поведение. Есть еще пара других, которых я нашел в кратком поиске «EAGAIN tee».

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


5
2018-03-14 19:26



Такая же ошибка - вы также можете легко ее протестировать самостоятельно - просто смените каталог на tar (он не должен быть слишком маленьким), а remote_ssh_account - на то, к которому у вас есть доступ без пароля.
Измененный; пожалуйста, попробуйте снова. Да, я знаю, что не делает именно то, что вы хотите, но я просто хочу попробовать. Убедитесь, что вы запускаете его таким же образом (т. Е. Как скрипт, а не непосредственно в командной строке). - BMDan
Это работает и доставляет файл. Хотя я действительно ценю помощь - тесты, подобные этому, могут выполняться повсюду - мой оригинальный скрипт не не для вас?
Я могу решить эту проблему, чтобы dd if=/dev/urandom bs=1M count=20 | tee >(md5sum - | ssh user@host 'cat - > /tmp/foo.md5') | ssh user@host 'cat > /tmp/foo.tar', Теперь мы работаем над отладкой. - BMDan
Это также происходит с изменением порядка (то есть с cat>tar внутри >()). Ухоженная. Добавление -i пометить tee (на слепой догадке) не помогло. - BMDan