在Bash脚本中嵌入短Python脚本
我想在一个bash脚本里嵌入一些简单的python脚本文本,比如说在我的.bash_profile
里。请问有什么好的方法可以做到这一点呢?
我目前的解决方案是用-c
选项来调用python解释器,并告诉它从stdin
读取内容并执行。这样,我就可以构建一些简单的工具,比如下面这个,帮助我处理文本,以便在我的交互式提示符中使用:
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 个回答
30
使用 bash 的 here document
有一个问题,就是脚本会通过 stdin
传给 Python,这样如果你想把 Python 脚本当作过滤器来用,就会变得很麻烦。一个替代的方法是使用 bash
的 process substitution
,像这样:
... | python <( echo '
code here
' ) | ...
如果脚本太长,你也可以在括号里面使用 here document
,像这样:
... | python <(
cat << "END"
code here
END
) | ...
在脚本内部,你可以像平常一样从标准输入/输出读写数据(例如,使用 sys.stdin.readlines
来读取所有输入)。
另外,python -c
也可以用,正如其他回答中提到的,但我喜欢用下面这种方式来格式化代码,同时还遵循 Python 的缩进规则(来源):
read -r -d '' script <<-"EOF"
code goes here prefixed by hard tab
EOF
python -c "$script"
只要确保 here document
中每一行的第一个字符是一个硬制表符。如果你需要把这个放在一个函数里面,我会用下面这个技巧,让它看起来对齐:
function somefunc() {
read -r -d '' script <<-"----EOF"
code goes here prefixed by hard tab
----EOF
python -c "$script"
}
66
为什么你需要使用 -c
呢?对我来说,这样做就可以了:
python << END
... code ...
END
而且不需要额外的东西。
41