Помещение подоболочки в фоновом режиме вместо ввода команды в фоновом режиме

У меня есть два сценария bash, которые пытаются проверить хосты:

Сценарий 1:

#!/bin/bash for ip in {1..254}; do ping -c 1 192.168.1.$ip | grep "bytes from" | cut -d" " -f 4 | cut -d ":" -f 1 & done 

Сценарий 2:

 #!/bin/bash for ip in {1..254}; do host=192.168.1.$ip (ping -c 1 $host > /dev/null if [ "$?" = 0 ] then echo $host fi) & done 

Поскольку я проверяю большой диапазон, я хотел бы обрабатывать каждую команду ping параллельно. Тем не менее, мой второй скрипт, похоже, не повторяет попытку попыток fork из-за ограничений ресурсов. Это приводит к тому, что второй скрипт имеет непоследовательные результаты, в то время как мой первый скрипт дает постоянные результаты, несмотря на то, что время от времени не развивается. Может кто-то объяснить это мне? Также есть в любом случае, чтобы повторить неудачные вилки?

Уже есть ответ, который дает улучшенный фрагмент кода для задачи, с которой были связаны исходные вопросы с постерами, в то время как он, возможно, еще не ответил на вопрос более непосредственно.

Речь идет о различиях

  • A) Исправление непосредственно «команды», vs
  • B) Помещение подоболочки на задний план (т. Е. С аналогичной задачей)

Позволяет проверить, что эти различия выполняются 2 теста

 # A) Backgrounding a command directly sleep 2 & ps 

выходы

 [1] 4228 PID TTY TIME CMD 4216 pts/8 00:00:00 sh 4228 pts/8 00:00:00 sleep 

в то время как

 # A) backgrounding a subhell (with similar tas) ( sleep 2; ) & ps 

выводит что-то вроде:

 [1] 3252 PID TTY TIME CMD 3216 pts/8 00:00:00 sh 3252 pts/8 00:00:00 sh 3253 pts/8 00:00:00 ps 3254 pts/8 00:00:00 sleep 

** Результаты теста:**

В этом тесте (который запускает только sleep 2 ) версия подоболочки действительно отличается, поскольку она будет использовать 2 дочерних процесса (т. fork() Две операции fork() / exec и PID) и, следовательно, больше, чем прямое фонирование команды.

В script 1 вопроса, однако, команда была не одним sleep 2s а вместо этого была pipe из 4-х команд, которая, если мы проверим в другом случае

  • C) Профилирование трубы четырьмя командами

    C) Профилирование трубы четырьмя командами

    сон 2s | сон 2s | сон 2s | сон 2s & ps

дает это

 [2] 3265 PID TTY TIME CMD 3216 pts/8 00:00:00 bash 3262 pts/8 00:00:00 sleep 3263 pts/8 00:00:00 sleep 3264 pts/8 00:00:00 sleep 3265 pts/8 00:00:00 sleep 3266 pts/8 00:00:00 ps 

и показывает, что действительно script 1 будет намного более высоким напряжением с точки зрения PIDs и fork() s.

В качестве приблизительной оценки сценарий использовал бы около 254 * 4 ~ = 1000 PID и, следовательно, даже больше, чем script 2 с 254 * 2 ~ = 500 PID. Любая проблема, возникающая из-за недостатка PIDs, кажется еще маловероятной, поскольку в большинстве случаев Linux-боксы

 $ cat /proc/sys/kernel/pid_max 32768 

дает вам 32-кратное значение PID, необходимое даже для script 1 и вовлеченные процессы / программы (например, sed , ping и т. д.) также вряд ли могут привести к непостоянным результатам.

Как уже упоминалось пользователем @derobert, реальная проблема, стоящая за неудачами scripts заключалась в том, что отсутствующая команда wait , а это означает, что после обработки команд в цикле конец скрипта и, следовательно, оболочка вызвали все дочерние процессы.

Это будет делать то, что вы ожидаете:

 #!/bin/bash function_ping(){ if ping -c 1 -w 5 $1 &>/dev/null; then echo "UP: $1" else echo "DOWN $1" fi } for ip in {1..254}; do function_ping 192.168.1.$ip & done wait 

Сохраните его как параллельное и выполните его.

Это помогает вам? Он может быть преобразован в большую функцию, которую можно использовать в быстром цикле, чтобы вы могли использовать свое воображаемое программирование.

Примечание. Вы должны использовать bash.