代码之家  ›  专栏  ›  技术社区  ›  Adam Outler

如何读取一系列变量的标准输出

  •  1
  • Adam Outler  · 技术社区  · 14 年前

    Establishing database connection
    chanid = 1952
    starttime = 2010-09-29 08:12:00
    endtime = 2010-09-29 08:30:00
    basename = 1952_20100929081200.mpg
    stars = 0.0
    

    我需要将这些信息读入bash脚本中同名的变量中。我的bash脚本如下

    #! /bin/bash
    
    /usr/local/bin/mythicalPythonBindings.py --filename='1952_20100929081200.mpg' --DBHostName='192.168.1.110' --DBName='mythconverg' --DBUserName='mythtv' --DBPassword='mythtv' --output=./ReturnFile.txt --display|
       while read line
         do 
         case "$line" in
             "basename = "* ) 
                  echo $line
                  basename=`echo "$line" |sed s/'basename = '//g`
                  echo $basename
             ;;
         esac
       done
    echo $basename
    #doing more stuff 
    

    问题是在我的thicalPythonBindings.py公司,它不导出变量。语句“echo$basename”(在管道输出内部)可以工作,但是seccond“echo$basename”(在管道输出外部)不工作。

    如何设置这些变量以便在脚本的其余部分中使用?

    4 回复  |  直到 14 年前
        1
  •  3
  •   Dennis Williamson    14 年前

    这个 while done :

    pythonfunc () {
        /usr/local/bin/mythicalPythonBindings.py --filename='1952_20100929081200.mpg' --DBHostName='192.168.1.110' --DBName='mythconverg' --DBUserName='mythtv' --DBPassword='mythtv' --output=./ReturnFile.txt --display
    }
    
    while ...
    do
        ...
    done < <(pythonfunc)
    echo $basename
    

    我会用

    read var equals value
    # do some validation
    declare $var=$value
    

    declare 这样可以避免使用 eval

        2
  •  0
  •   Jonathan Leffler    14 年前

    两个关键变化:

    #! /bin/bash
    /usr/local/bin/mythicalPythonBindings.py --filename='1952_20100929081200.mpg' \
        --DBHostName='192.168.1.110' --DBName='mythconverg' --DBUserName='mythtv' \
        --DBPassword='mythtv' --output=./ReturnFile.txt --display |
    {
    while read var equals value
    do
        if [ $equals = "=" ]
        then
            eval $var=\"$value\"
        fi
    done
    
    echo basename=$basename
    echo starttime=$starttime
    echo endtime=$endtime
    echo stars=$stars
    echo chanid=$chanid
    # ...rest of script...
    }
    
    1. 使用壳牌公司的内置拆分工具,以及 eval 设置变量而不需要知道变量是什么(也不需要为每个不同的变量分配单独的赋值)。测试忽略输出的第一行。
    2. 使用{的I/O分组工具。。。}捕获脚本的其余部分,以便循环中设置的变量在循环之后可用。

        3
  •  0
  •   DigitalRoss    14 年前
    #!/bin/sh
    ./testpyscri.sh | (
       while read line
         do 
         case "$line" in
             "basename = "* ) 
        echo $line
                  basename=`echo "$line" |sed s/'basename = '//g`
                    echo $basename
             ;;
         esac
       done
       echo and also $basename
    )
    

    我做了一些修改,以方便地复制和演示结果,但唯一重要的修改是添加了一组paren。

    so ross$ ./testpyscri.sh  | ./pyscri.sh 
    basename = 1952_20100929081200.mpg
    1952_20100929081200.mpg
    and also 1952_20100929081200.mpg
    

    很容易理解上面的设计模式,它实际上可以在管道的两端执行任意复杂的脚本。但也许你想要一种不同的设计。尝试以下操作:

    so ross$ expand < test.sh
    #!/bin/sh
    # here is an alternate design pattern
    if [ x$1 != x-a ]; then
      echo abc | ./$0 -a
      exit 0
    fi
    read x
    echo $x
    so ross$ ./test.sh
    abc
    so ross$ 
    
        4
  •  0
  •   gsbabil    14 年前

    eval 它假设:

    1. Python输出以分隔的变量和值 = .
    2. 使用Awk和 -F '=' 把输入分解成 variable value
    3. 使用Sed删除变量和值的前导和尾随空格字符。

    Bash代码:

    #!/bin/bash
    
    while read line
    do
        var=$(echo $line | awk -F '=' '{print $1}' | sed 's/^[ \t]*//;s/[ \t]*$//')
        val=$(echo $line | awk -F '=' '{print $2}' | sed 's/^[ \t]*//;s/[ \t]*$//')
    
        eval $var="$val"
        echo $python_var
    done
    

    用法示例:

    >> echo "python_var = 1234" | ./script.sh 
    >> 1234