Shell变量作用域

解决Hadoop Unhealthy Nodes问题,以及Zookeeper的清理

问题

从文件中逐行读入数据进行处理,但是保存的处理结果在while循环就失效了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
while read line
do
str[$i]=$line1
echo $i
echo ${str[i]}
let i=i+1
done < data

len=${#str[@]}
echo $len

# $len长度为实际data文件的行数
# str[]变量的作用域一直有效

##########################

cat data|while read line
do
str[$i]=$line1
echo $i
echo ${str[i]}
let i=i+1
done

len=${#str[@]}
echo $len

# $len长度为0
# 说明str[]变量的作用域到done结束即失效。

原因

局部变量是普通的变量,仅在创建它的Shell中有效。
cat data|while read line 使用了管道符 “|”
表明父shell中的局部变量不会传递到子shell中

管道的本质:

管道是一种两个进程间进行单向通信的机制。因为管道传递数据的单向性,管道又称为半双工管道。管道的这一特点决定了器使用的局限性。管道是Linux支持的最初Unix IPC形式之一,具有以下特点:

  • 数据只能由一个进程流向另一个进程(其中一个读管道,一个写管道);如果要进行双工通信,需要建 立两个管道。
  • 管道只能用于父子进程或者兄弟进程间通信。,也就是说管道只能用于具有亲缘关系的进程间通信。

除了以上局限性,管道还有其他一些不足,如管道没有名字(匿名管道),管道的缓冲区大小是受限制的。管道所传输的是无格式的字节流。这就需要管道输入方和输出方事先约定好数据格式。虽然有那么多不足,但对于一些简单的进程间通信,管道还是完全可以胜任的。

使用管道进行通信时,两端的进程向管道读写数据是通过创建管道时,系统设置的文件描述符进行的。从本质上说,管道也是一种文件,但它又和一般的文件有所不同,可以克服使用文件进行通信的两个问题,这个文件只存在内存中。

通过管道通信的两个进程,一个进程向管道写数据,另外一个从中读数据。写入的数据每次都添加到管道缓冲区的末尾,读数据的时候都是从缓冲区的头部读出数据的。

如果文章对您有帮助,感谢您的赞助支持!