• 学艺不精,又被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可能因为换行符的原因读取不了最后一行

  • 相关阅读:
    输入/输出的格式和方法
    程序编译运行和exe运行之文件位置的区别
    ZOJ_3950_How Many Nines 解题报告及如何对程序进行测试修改
    [Offer收割]编程练习赛13 解题报告
    查找语言自带函数
    codeblocks下的汇编语言
    hiho一下 第144周(机会渺茫)解题报告及拓展
    关闭调试窗口快捷方式
    编写程序一个位置的快速到达和修改
    poj3660(Cow Contest)解题报告
  • 原文地址:https://www.cnblogs.com/coding-my-life/p/4197115.html
Copyright © 2020-2023  润新知