Bash:子进程访问变量 [英] Bash: Subprocess access variables

查看:101
本文介绍了Bash:子进程访问变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想编写一个Bash脚本,该脚本通过ssh登录到多台计算机,并首先显示其主机名并执行命令(在每台计算机上使用同一命令).主机名和命令的输出应一起显示.我想要一个并行版本,因此ssh-commands应该在后台并行运行.

I want to write a Bash-Script which loggs into several machines via ssh and first shows their hostname and the executes a command (on every machine the same command). The hostname and the output of the command should be displayed together. I wanted a parallel version, so the ssh-commands should be run in background and in parallel.

我在下面构造了bashscripted. 问题是:由于runonip-函数在子shell中执行,因此无法访问DATA-数组来存储结果.是否可以通过通过引用传递"功能来使子外壳访问Array?

I constructed the bashscripted attached below. The problem is: As the runonip-function is executed in a subshell, it got no access to the DATA-array to store the results. Is it somehow possible to give the subshell access to the Array, perhaps via a "pass by reference" to the function?

代码:

 #!/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;

推荐答案

不,实际上不是.子外壳程序在完全独立的操作系统进程中运行,并且两个进程共享内存的唯一方法是使它们的代码通过系统调用显式地进行设置. Bash不会那样做.

No, it's really not. The subshell runs in an entirely separate operating system process, and the only way for two processes to share memory is for their code to set that up explicitly with system calls. Bash doesn't do that.

您需要做的是找到其他方法使两个进程进行通信.以PID命名的临时文件是一种方法:

What you need to do is find some other way for the two processes to communicate. Temporary files named after the PIDs would be one way:

#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;

这篇关于Bash:子进程访问变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆