Bash: переменные доступа к подпроцессам - PullRequest
3 голосов
/ 02 марта 2010

Я хочу написать Bash-Script, который регистрируется на нескольких машинах через ssh и сначала показывает их имя хоста и выполняет команду (на каждой машине одна и та же команда). Имя хоста и выходные данные команды должны отображаться вместе. Я хотел параллельную версию, поэтому ssh-команды должны выполняться в фоновом режиме и параллельно.

Я создал bash-скрипт, прикрепленный ниже. Проблема заключается в следующем: поскольку функция runonip выполняется в подоболочке, она не получила доступа к массиву DATA для хранения результатов. Возможно ли как-то дать доступ к массиву в подоболочке, возможно, через «передачу по ссылке» в функцию?

Код:

 #!/bin/bash
set -u

if [ $# -eq 0 ]; then
   echo "Need Arguments: Command to run"
   exit 1
fi 

DATA=""
PIDS=""

#Function to run in Background for each ip
function runonip {
    ip="$1"
    no="$2"
    cmds="$3"
    DATA[$no]=$( {
        echo "Connecting to $ip"
        ssh $ip cat /etc/hostname
        ssh $ip $cmds
    } 2>&1 )
}

ips=$(get ips somewhere)

i=0
for ip in $ips; do
    #Initialize Variables
    i=$(($i+1))
    DATA[$i]="n/a"

    #For the RunOnIp Function to background
    runonip $ip $i $@ &

    #Save PID for later waiting
    PIDS[$i]="$!"
done

#Wait for all SubProcesses
for job in ${PIDS[@]}; do
    wait $job
done

#Everybody finished, so output the information from DATA
for x in `seq 1 $i`; do
    echo ${DATA[$x]}
done;

Ответы [ 2 ]

5 голосов
/ 02 марта 2010

Нет, это действительно не так. Подоболочка работает в совершенно отдельном процессе операционной системы, и единственный способ для двух процессов совместно использовать память - их код явно устанавливает это с помощью системных вызовов. Баш этого не делает.

Что вам нужно сделать, так это найти какой-то другой способ взаимодействия двух процессов. Временные файлы, названные в честь PID, могут быть односторонними:

#For the RunOnIp Function to background
runonip $ip $i $@ >data-tmp&
mv data-tmp data-$!

А затем кошка файлов:

#Everybody finished, so output the information from the temp files
for x in ${PIDS[@]}; do
    cat data-$x
    rm data-$x
done;
3 голосов
/ 02 марта 2010

Возможно, вы сможете настроить именованный канал для межпроцессного взаимодействия.

Другая возможность в Bash 4 может заключаться в использовании сопроцессов .

Дополнительные ссылки:

...