学艺不精,又被shell的管道给坑了

  我用过bash shell,而且时间不短了。但我从来没学过shell,至少没有像C++这么认真去学。平时写些基本的脚本没问题,不懂也可以google、百度。可在2014最后一天,掉坑里了。

  其实脚本也很简单,代码基本如下:

#!/bin/bash

declare -A FILES    #关联数组 bash version >= 4.0

cat EX_FILES | while read line
do
    key=`echo $line | awk ‘{print $1}‘`
    value=`echo $line | awk ‘{print $2}‘`
    FILES[$key]=$value
done

echo ${FILES[@]}

其实也就是从文件每次读出一行,再从一行中按列分解出key、value,然后再赋值到map里去。可以,输出的map居然为空。于是,开始了几个钟头的折腾。

  一开始以为是关联数组的原因,因为是第一次用关联数组。可是google、百度,man bash,都是这么用的。在FILES[$key]=$value这里打印也是正确的,到while之外FILES却是空的。然后怀疑是因为key是字符串的原因,于是另起一个脚本测试,key为字符串完全没问题。想想这种情况应该是FILES成了局部变量(按C++的方式,这么想的),可我声明FILES时没用local啊。难道是while read的原因?于是搜索了一下"while read 局部变量",搜索到了大量的sub shell相关的问题,也正是我的问题。

  在 cat EX_FILES | while ...done 这代码中,cat EX_FILES是在当前shell中运行,while ...done是在子shell中运行,所以当前shell的数组没有被赋值。解决的方法改一下就好:

#!/bin/bash

declare -A FILES
while read line
do
    key=`echo $line | awk ‘{print $1}‘`
    value=`echo $line | awk ‘{print $2}‘`
    FILES[$key]=$value
done < EX_FILES

echo ${FILES[@]}

这样要注意EX_FILES可能因为换行符的原因读取不了最后一行

时间: 2024-12-13 08:48:11

学艺不精,又被shell的管道给坑了的相关文章

shell别名,管道,用户配置文件,变量,read

一.shell基础 cat /etc/shells  当前操作系统可以使用的shell 什么是shell 实现某种功能的,有执行权限的文本文件 命令行解释器 内建命令 (系统内部提供的命令) 外建命令 (安装对应的软件包才有的命令) type cd //查看cd是属于什么类型的命令 支持快捷键 支持tab健补全 历史命令history -c    //清除历史命令 -w    //马上保存刚执行的命令进.bash_history 别名 如何查看当有系统已有别名命令 alias 如何自定义别名命令

shell 命名管道,进程间通信, ncat作http server

命名管道基础 命名管道也被称为FIFO文件, 在文件系统中是可见的,并且跟其它文件一样可以读写! 命名管道特点: 当写进程向管道中写数据的时候,如果没有进程读取这些数据,写进程会堵塞 当读取管道中的数据的时候,如果没有数据,读取进程会被堵塞 当写进程堵塞的时候,有读进程读取数据,那么写进程恢复正常 当读进程堵塞的时候,如果写进程写了数据,那么读进程会读取数据,然后正常执行后面的代码 # 写进程堵塞的情况 [[email protected]_10.2.1.242 test]$ echo 1 >p

十二、Shell篇——管道与重定向

前言 管道:进程通信的一个通信工具重定向:可以将程序结果输出到某个文件,也可以将文件代替键盘作为输入 管道与管道符 管道和信号一样,也是进程通信的方式之一匿名管道(管道符)是Shell编程经常用到的通信工具管道符是"|",将前一个命令执行的结果传递给后面的命令 ps | cat (1)将第一条命令的输出作为第二条命令的输入 [email protected] Git % ls -l | more (2)cat和ps都是外建命令,管道符会为这两条命令建立一个子进程(ps命令运行完了所以看

shell——mkfifo管道

转自:http://blog.sina.com.cn/s/blog_605f5b4f0101azuc.html 创建命名管道的方法为:mkfifo pipe_name. 这样就能创建一个命名的管道pipe_name. 运行命令并把输出重定向到管道并扔后台(否则会hang住):cmd > pipe_name & 读取管道内容:cat < pipe_name便可读取管道中的内容. tmp_fifofile="/tmp/$$.fifo" mkfifo $tmp_fifof

Bash Shell 的管道命令

1.cut: 命令选取 cut -d'分隔字符' -f fields -d :后面接分隔字符,用-f一起使用 -f: 依据-d的分隔字符将一段信息切割成为数段 -c:以字符的单位取出固定字符区间 Eg :echo $PATH | cut -d':'-f 5 以":"作为分隔,取第五段字符 2.grep :上面cut命令是在一行信息当中取出某部分,而grep则是分析一段信息,取出所要行 grep [-acinv] [–color=auto] '查找字符串' file -a : 将bina

Python踩坑之旅其一杀不死的Shell子进程

1.1 踩坑案例 踩坑的程序是个常驻的Agent类管理进程, 包括但不限于如下类型的任务在执行: a. 多线程的网络通信包处理 和控制Master节点交互 有固定Listen端口 b. 定期作业任务, 通过subprocess.Pipe执行shell命令 c. etc 发现坑的过程很有意思: a.重启Agent发现Port被占用了 => 立刻想到可能进程没被杀死, 是不是停止脚本出问题 => 排除发现不是, Agent进程确实死亡了 => 通过 netstat -tanop|grep p

Shell文本处理三剑客(三)

防伪码:锄禾日当午,汗滴禾下土. 8.3.7 7 内置函数 函数  描述 int(expr)  截断为整数 sqrt(expr)  平方根 rand()  返回一个随机数 N,0 和 1 范围,0 < N < 1 srand([expr]) 使用 expr 生成随机数,如果不指定,默认使用当前时间为种子,如 果前面有种子则使用生成随机数 asort(a, b) 对数组 a 的值进行排序,把排序后的值存到新的数组 b 中,新排序 的数组下标从 1 开始 asorti(a,b)  对数组 a 的下

linux常用命令整理(五):shell基础

大家好,我是会唱歌的程序猿------ 最近在学习linux,闲暇之余就把这些基本的命令进行了整理,希望大家能用的上,整理的的目的是在忘了的时候翻出来看看^?_?^,前后一共分为五个部分: linux基本命令整理(一):常用命令 地址:http://www.cnblogs.com/devinCat/p/7247824.html linux基本命令整理(二):用户.用户组.文件系统和网络 地址:http://www.cnblogs.com/devinCat/p/7247847.html linux

shell第四篇(下)

摘自王垠的:Unix的缺陷 我想通过这篇文章解释一下我对 Unix 哲学本质的理解.我虽然指出 Unix 的一个设计问题,但目的并不是打击人们对 Unix 的兴趣.虽然 Unix 在基础概念上有一个挺严重的问题,但是经过多年的发展之后,这个问题恐怕已经被各种别的因素所弥补(比如大量的人力).但是如果开始正视这个问题,我们也许就可以缓慢的改善系统的结构,从而使得它用起来更加高效,方便和安全,那又未尝不可.同时也希望这里对 Unix 命令本质的阐述能帮助人迅速的掌握 Unix,灵活的应用它的潜力,避