ограничение xargs от чтения стандартного ввода в буфер

Похоже, что xargs читает входные строки из стандартного ввода, даже если он уже запускает максимальное количество процессов, которые он может запустить.

Вот пример:

#!/bin/bash
function xTrigger()
{
   for ii in `seq 1 100`; do echo $ii; sleep 2; done
}
function xRunner()
{
   sleep 10;
   echo $1;
}
export -f xTrigger
export -f xRunner
bash -c "xTrigger" | xargs -n 1 -P 1 -i bash -c "xRunner {}"

Через 20 секунд после запуска описанного выше процесса я killall xTrigger, но xargs буферизует все, что выводит xTrigger, поэтому xRunner продолжает печатать 1..10. Я хочу, чтобы он печатал только 1,2

Можно ли каким-либо образом изменить это поведение и заставить xargs читать из стандартного ввода только тогда, когда он хочет запустить новую команду, чтобы xTrigger ждал в операторе echo, пока xargs не прочитает из него? Мой стандартный ввод имеет очень динамичный контент, поэтому это было бы очень полезно.

Попытка придерживаться xargs только потому, что это было бы стабильно и элегантно. Хотите написать дополнительный код, только если нет простого способа сделать это с помощью xargs.

Спасибо за вашу помощь!


person Sahas    schedule 22.02.2011    source источник
comment
bash: xTrigger: command not found - ваша функция не передается подоболочке, не так ли? То же самое с xRunner. Почему бы тебе не сделать xTrigger | xargs -n 1 -P 1 -i xRunner? И где мы это делаем: обратные кавычки устарели, вместо этого используйте $(...), потому что это лучше читаемо, независимо от шрифта и легко вкладывается. И последнее: for ii in {1..100} лучше, потому что он встроенный и не нуждается во внешней программе seq. Пока я не знаю ответа на ваш главный вопрос, но догадываюсь: нет, не полетит. Как это должно быть? По параметру? Путем модификации кода и перекомпиляции? Разве кеш не является центральной идеей xargs?   -  person user unknown    schedule 22.02.2011
comment
xTrigger | xargs -n 1 -P 1 -i xRunner тоже не работает, потому что канал запускает подоболочку, не так ли? Итак, вам нужны 2 скрипта, xTrigger.sh и xRunner.sh, и они нужны в любом случае, потому что вы не можете остановить функцию с помощью killall - не так ли?   -  person user unknown    schedule 22.02.2011
comment
простите, забыл пару строк. Отредактированный код, чтобы исправить это. это процессы, использующие процессы, чтобы мы могли их убить, а xargs не может запустить процесс, поэтому мы должны использовать bash -c 'имя_функции'   -  person Sahas    schedule 22.02.2011
comment
ой. Я имел в виду, что xargs не может запустить функцию   -  person Sahas    schedule 22.02.2011
comment
xargs не может узнать, что процесс слева умер, если процесс справа заблокирован.   -  person Dennis Williamson    schedule 22.02.2011
comment
Это имеет смысл. Я написал несколько дополнительных строк кода для решения проблемы, опубликованной ниже.   -  person Sahas    schedule 23.02.2011


Ответы (3)


Разве вам не нужно убивать Bash PID xTrigger()?

bash -c "echo $$; xTrigger" | xargs -n 1 -P 1 bash -c 'xRunner "$@"' _
kill -HUP <PID>
person jim    schedule 22.02.2011

В моей системе xargs по умолчанию останавливается, если одно из выполняемых заданий завершается с ненулевым кодом возврата. Следовательно, вы должны отправлять сигнал pid bash, на котором работает XRunner.

person frankc    schedule 22.02.2011

Получил xTrigger для создания следующего триггера только тогда, когда нет запущенных заданий «bash -c xRunner». Теперь отлично работает:

#!/bin/bash
function xTrigger()
{
   for ii in `seq 1 100`; do 
      echo $ii; 
      while [[ $(psgrep xRunner|grep -v xargs|wc -l) -ge 1 ]]; do
         sleep 2; 
      done
   done
}
function xRunner()
{
   sleep 10;
   echo $1;
}
export -f xTrigger
export -f xRunner
bash -c "xTrigger" | xargs -n 1 -P 1 -i bash -c "xRunner {}"
person Sahas    schedule 22.02.2011