Как данные обрабатываются по каналам? - PullRequest
0 голосов
/ 24 января 2011

Я использовал эту программу командной строки, которую нашел в другом посте на SO , описывающем, как сделать паук на сайте.

wget --spider --force-html -r -l2 http://example.com 2>&1 | grep '^--' | awk '{ print $3 }' | grep -v '\.\(css\|js\|png\|gif\|jpg\)$' > wget.out

Когда я сканирую большой сайт, его завершение занимает много времени. Между тем, файл wget.out на диске показывает нулевой размер. Так когда же данные по каналам обрабатываются и записываются в файл на диске? Это после каждого этапа в трубе дойти до завершения? В этом случае заполнится ли wget.out после завершения сканирования?

Как заставить программу периодически записывать на диск, чтобы, даже если этап сканирования был прерван, у меня был сохранен какой-то вывод?

1 Ответ

1 голос
/ 24 января 2011

В каждой трубе есть буферизация, и, возможно, в слоях stdio каждой программы. Данные не попадут на диск до тех пор, пока окончательная команда grep не обработает достаточно строк, чтобы ее буферы заполнились до такой степени, что они будут пролиты на диск.

Если вы запустите свой конвейер в командной строке, а затем нажмете Ctrl - C , sigint будет отправлено каждому процессу, завершит каждый и потеряет все ожидающие выход.

Или:

  1. Игнорировать sigint во всех процессах, кроме первого. Bash hackery следует:

    $ wget --spider --force-html -r -l2 http://example.com 2>&1 grep '^--' |
        { trap '' int; awk '{ print $3 }'; } |
        ∶
    
  2. Просто доставьте прерывание клавиатуры первому процессу. Интерактивно вы можете найти pid с помощью jobs -l, а затем kill. (Запустите конвейер в фоновом режиме.)

    $ jobs -l
    [1]+ 10864 Running          wget
       3364 Running             | grep
      13500 Running             | awk
    ∶
    $ kill -int 10864
    
  3. Поиграйте со встроенным disown bash.

...