| while read X "> | while read X Y X; do ... done"使用 因为在ba..."> | while read X " />
美文网首页
bash千万不要这样" | while read X

bash千万不要这样" | while read X

作者: CodingCode | 来源:发表于2020-08-10 05:18 被阅读0次

    bash千万不要这样"<cmd> | while read X Y X; do ... done"使用

    因为在bash里面”|"后命令是在一个新的shell里面运行的,即“|”前后不在一个进程里面,所以如果在while循环里面使用了变量之类的赋值,就会无效。

    举个例子:

    #!/bin/bash
    
    VAR=AAA
    echo ${VAR}
    
    echo "Hello World" | tr ' ' '\n' | while read WORD; do
      VAR=BBB
      echo ${VAR}
    done
    
    echo ${VAR}
    

    运行结果:

    AAA
    BBB
    BBB
    AAA
    

    看到在while循环内尽管已经把VAR置成了BBB,但是在循环退出后,VAR的值还是回退到AAA,也就是循环内变量赋值无效。
    为什么呢,因为while循环实在一个独立的进程空间里面运行的,在那个进程内把VAR改成了BBB,但是并不影响在外面主进程的空间。

    我们把PID打出来看看:

    VAR=AAA
    echo ${VAR}
    echo PID=$$
    
    echo "Hello World" | tr ' ' '\n' | while read WORD; do
      VAR=BBB
      echo ${VAR}
      echo PID=$$
    done
    
    echo ${VAR}
    echo PID=$$
    

    运行:

    AAA
    PID=87654
    BBB
    PID=87654
    BBB
    PID=87654
    AAA
    PID=87654
    

    貌似PID也一样啊,不是吗?
    不是的,因为打印PID的用法错误了,"$$"在脚本启动的时候就解析完了,全部替换成了当前进程的PID所以都一样;我们改一下:

    #!/bin/bash
    
    VAR=AAA
    
    echo ${VAR}
    cut -d' ' -f4 < /proc/self/stat
    
    echo "Hello World" | tr ' ' '\n' | while read WORD; do
      VAR=BBB
      echo ${VAR}
      cut -d' ' -f4 < /proc/self/stat
    done
    
    echo ${VAR}
    cut -d' ' -f4 < /proc/self/stat
    

    在运行:

    AAA
    87896
    BBB
    87900
    BBB
    87900
    AAA
    87896
    

    这里就可以看出while循环内的PID和循环外的PID是不一样的。

    那应该怎么用呢:
    答:

    while read X, Y, X; do
    ...
    done < <(<cmd>)
    

    例:

    #!/bin/bash
    
    VAR=AAA
    
    echo ${VAR}
    cut -d' ' -f4 < /proc/self/stat
    
    while read WORD; do
      VAR=BBB
      echo ${VAR}
      cut -d' ' -f4 < /proc/self/stat
    done < <(echo "Hello World" | tr ' ' '\n')
    
    echo ${VAR}
    cut -d' ' -f4 < /proc/self/stat
    

    得到运行结果:

    AAA
    89047
    BBB
    89047
    BBB
    89047
    BBB
    89047
    

    相关文章

      网友评论

          本文标题:bash千万不要这样" | while read X

          本文链接:https://www.haomeiwen.com/subject/glkddktx.html