在 bash 脚本中嵌入短的 python 脚本

我想在 bash 脚本中嵌入短的 python 脚本文本,以便在我的 .bash_profile中使用。做这件事的最好方法是什么?

到目前为止,我的解决方案是使用 -c选项调用 python 解释器,并将解释器从 stdin读取的任何内容告诉 exec。从那里,我可以构建像下面这样的简单工具,允许我处理用于交互式提示符的文本:

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 解释器的角度做一些愚蠢的事情。

78070 次浏览

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

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

不需要任何额外的东西。

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

python - <<END

请参阅命令行引用 给你

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

他并没有询问如何在 bash 脚本中执行 python 代码,而是实际上让 python 设置了环境变量。

将其放入 bash 脚本中,并尝试让它说“它工作了”。

export ASDF="it didn't work"


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


echo $ASDF

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

如果有解决办法,我也想看看。

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

#!/bin/bash


ASDF="it didn't work"


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


echo $ASDF

如果使用 zsh,可以使用 zsh 的 加入和 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解决方案更好。

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

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


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

使用 bash here document的一个问题是,脚本然后在 stdin上传递给 Python,因此如果您想使用 Python 脚本作为过滤器,那么它会变得很笨拙。另一种选择是使用 bashprocess substitution,类似于这样:

... | python <( echo '
code here
' ) | ...

如果脚本太长,也可以在括号内使用 here document,如下所示:

... | python <(
cat << "END"
code here
END
) | ...

在脚本内部,您可以像通常那样从/读/写标准 i/o (例如,sys.stdin.readlines吞噬所有输入)。

另外,python -c也可以像其他答案中提到的那样使用,但是下面是我希望如何在遵守 Python 的缩进规则(演职员表)的同时进行良好的格式化:

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

只要确保这里文档中每行的第一个字符是硬选项卡即可。如果你必须把它放在一个函数里面,那么我使用下面的技巧,我在某个地方看到它看起来是对齐的:

function somefunc() {
read -r -d '' script <<-"----EOF"
code goes here prefixed by hard tab
----EOF
python -c "$script"
}

准备复制粘贴输入示例:

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


echo $output

试试这个:

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