在bash脚本中嵌入短python脚本

时间:2010-02-03 01:36:42

标签: python bash

我想在bash脚本中嵌入短python脚本的文本,比如我的.bash_profile。做这样的事情最好的方法是什么?

我到目前为止的解决方案是使用-c选项调用python解释器,并告诉解释器execstdin读取的内容。从那里,我可以构建如下的简单工具,允许我处理文本以便在我的交互式提示中使用:

function pyexec() {
    echo "$(/usr/bin/python -c 'import sys; exec sys.stdin.read()')"
}

function traildirs() {
    pyexec <<END
trail=int('${1:-3}')
import os
home = os.path.abspath(os.environ['HOME'])
cwd = os.environ['PWD']
if cwd.startswith(home):
    cwd = cwd.replace(home, '~', 1)
parts = cwd.split('/')
joined = os.path.join(*parts[-trail:])
if len(parts) <= trail and not joined.startswith('~'):
    joined = '/'+joined
print joined
END
}

export PS1="\h [\$(traildirs 2)] % "

这种方法对我来说闻起来有点滑稽,我想知道这样做的替代方法可能是什么。

我的bash脚本编写技巧非常简陋,所以我特别感兴趣的是,从bash解释器的角度来看,我是否正在做一些愚蠢的事情。

9 个答案:

答案 0 :(得分:42)

为什么需要使用-c?这对我有用:

python << END
... code ...
END

不需要任何额外的东西。

答案 1 :(得分:29)

python解释器在命令行上接受-作为stdin的同义词,因此您可以将对pyexec的调用替换为:

python - <<END

请参阅命令行参考here

答案 2 :(得分:14)

使用bash here document的一个问题是脚本然后在stdin上传递给Python,所以如果你想使用Python脚本作为过滤器,它会变得难以处理。另一种方法是使用bash的{​​{1}},如下所示:

process substitution

如果脚本太长,你也可以在paren中使用... | python <( echo ' code here ' ) | ... ,如下所示:

here document

在脚本中,您可以像往常一样从/向标准i / o进行读/写(例如,... | python <( cat << "END" code here END ) | ... 以吞噬所有输入。)

另外,sys.stdin.readlines可以像其他答案中提到的那样使用,但是我喜欢这样做,以便格式化,同时仍然遵守Python的缩进规则(credits):

python -c

确保此处文档中每行的第一个字符是一个硬标签。如果你必须将它放在一个函数中,那么我使用我在某处看到的下面的技巧使它看起来是对齐的:

read -r -d '' script <<-"EOF"
    code goes here prefixed by hard tab
EOF
python -c "$script"

答案 3 :(得分:7)

如果你需要在bash脚本中使用python的输出,你可以这样做:

#!/bin/bash

ASDF="it didn't work"

ASDF=`python <<END
ASDF = 'it worked'
print ASDF
END`

echo $ASDF

答案 4 :(得分:7)

有时在这里使用文档并不是一个好主意。另一种方法是使用python -c:

py_script="
import xml.etree.cElementTree as ET,sys
...
"

python -c "$py_script" arg1 arg2 ...

答案 5 :(得分:5)

准备使用输入复制粘贴示例:

input="hello"
output=`python <<END
print "$input world";
END`

echo $output

答案 6 :(得分:2)

有趣......我现在也想要一个答案; - )

他不是在如何在bash脚本中执行python代码,而是实际拥有python set环境变量。

将它放在一个bash脚本中并尝试让它说“它工作正常”。

export ASDF="it didn't work"

python <<END
import os
os.environ['ASDF'] = 'it worked'
END

echo $ASDF

问题是python是在环境的副本中执行的。在python退出后,不会看到对该环境的任何更改。

如果有解决方案,我也很乐意看到它。

答案 7 :(得分:1)

试试这个:

#!/bin/bash
a="test"
python -c "print  '$a this is a test'.title()"

答案 8 :(得分:0)

如果您使用zsh,可以使用zsh&#39; s join和python stdin选项(python -)将Python嵌入到脚本中:

py_cmd=${(j:\n:)"${(f)$(
    # You can also add comments, as long as you balance quotes
    <<<'if var == "quoted text":'
    <<<'  print "great!"')}"}

catch_output=$(echo $py_cmd | python -)

您可以缩进Python代码段,因此在内部函数时它看起来比EOF<<END解决方案更好。