我有一个名为mythicalPythonBindings.py的python脚本。它输出类似
的内容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
问题是当在mythicalPythonBindings.py的管道输出中设置变量时,它不会导出变量。语句“echo $ basename”(在管道输出中)有效,但是第二个“echo $ basename”(在管道输出之外)不起作用。
如何设置这些变量以用于脚本的其余部分?
编辑:我需要在其他命令中使用此变量,而不将数据保存到以后必须删除的文件中。
答案 0 :(得分:3)
while
循环在输入内容时创建子shell。为避免这种情况,您可以将流程替换重定向到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
。
答案 1 :(得分:0)
#!/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
)
我进行了一些更改以轻松复制和演示结果,但唯一重要的变化是添加了单组parens。
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$
答案 2 :(得分:0)
两个关键变化:
#! /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...
}
eval
来设置变量,而无需知道变量是什么(并且没有为每个不同的变量分别进行分配)。测试忽略输出的第一行。您可以使用括号代替大括号;在这种情况下,它相同的事情。通常,I / O分组不会启动子shell,这对于在执行代码块时避免重复重定向很有用,同时仍允许在块外部看到设置在代码块中的变量。
答案 3 :(得分:0)
这是使用eval
的另一个版本
它假定:
=
分隔的变量和值。-F '='
的Awk将输入分解为variable
和value
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