在bash脚本中嵌入短python脚本

Mat*_*son 52 python bash

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

我到目前为止的解决方案是使用-c选项调用python解释器,并告诉解释器exec它读取的内容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)] % "
Run Code Online (Sandbox Code Playgroud)

这种方法虽然闻起来有点滑稽,但我想知道这样做的替代方法可能是什么.

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

Ric*_*nes 43

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

python << END
... code ...
END
Run Code Online (Sandbox Code Playgroud)

无需任何额外的东西.

  • 小心你如何命名heredoc标记.如果在您的示例中没有引用它,则shell扩展将在heredoc字符串中发生.例如,如果你的python代码只包含`print'$ SHELL',那么输出将是`/ bin/bash`或者你的shell恰好是什么.如果将第一行更改为`python - <<'END'`,则输出将为`$ SHELL`.如果您要复制并粘贴现有代码以嵌入bash脚本,那么您几乎肯定不希望shell替换 - 您希望代码的运行方式与它未嵌入bash脚本时的运行方式相同,对吧? (8认同)
  • 为了将输出收集到变量中,我做了`ABC = $(python << END` ...`END)`并且它有效. (2认同)
  • 然后你需要“-”,就像内德的回答一样。参数将跟在破折号后面。 (2认同)

Ned*_*ily 33

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

python - <<END
Run Code Online (Sandbox Code Playgroud)

请参阅此处的命令行参考.

  • 一个完整的例子会很好。 (2认同)

har*_*dsv 16

使用bash的一个问题here document是脚本然后传递给Python stdin,所以如果你想使用Python脚本作为过滤器,它就变得难以处理.一种选择是使用bash's process substitution,这样的东西:

... | python <( echo '
code here
' ) | ...
Run Code Online (Sandbox Code Playgroud)

如果脚本太长,你也可以here document在paren中使用,如下所示:

... | python <(
cat << "END"
code here
END
 ) | ...
Run Code Online (Sandbox Code Playgroud)

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

另外,python -c可以像其他答案中提到的那样使用,但是我喜欢这样做以便格式化,同时仍然尊重Python的缩进规则(信用):

read -r -d '' script <<-"EOF"
    code goes here prefixed by hard tab
EOF
python -c "$script"
Run Code Online (Sandbox Code Playgroud)

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

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

  • 为什么0赞成?如果你想在你的程序中使用sys.stdin,这是唯一正确的答案! (3认同)
  • 这是最好的解决方案,请支持它! (2认同)

Don*_* Li 8

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

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

python -c "$py_script" arg1 arg2 ...
Run Code Online (Sandbox Code Playgroud)


des*_*gua 7

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

#!/bin/bash

ASDF="it didn't work"

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

echo $ASDF
Run Code Online (Sandbox Code Playgroud)


Adr*_*pez 6

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

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

echo $output
Run Code Online (Sandbox Code Playgroud)