【问题标题】:python -c vs python -<< heredocpython -c vs python -<< heredoc
【发布时间】:2015-08-22 12:40:55
【问题描述】:

我正在尝试在 Bash 脚本中运行一些 Python 代码,所以我想了解两者之间的区别:

#!/bin/bash
#your bash code

python -c "
#your py code
"

python - <<DOC
#your py code
DOC

我检查了网络,但无法编译有关该主题的内容。你认为一个比另一个更好吗? 如果你想从 Python 代码块返回一个值到你的 Bash 脚本,那么heredoc 是唯一的方法吗?

【问题讨论】:

  • 在您的第一个示例中,如果您想使用带双双引号的字符串,则需要转义双引号。
  • 好吧 Evert,这是一方面。其他人更喜欢哪一个?
  • 这确实是关于这里文档而不是关于 Python 的问题

标签: python bash heredoc


【解决方案1】:

使用 here 文档的主要缺陷是脚本的标准输入将是 here 文档。因此,如果您有一个想要处理其标准输入的脚本,python -c 几乎是您唯一的选择。

另一方面,使用python -c '...' 会根据shell 的需要绑定单引号,因此您只能在Python 脚本中使用双引号字符串;使用双引号来保护脚本免受 shell 的影响会带来额外的问题(双引号中的字符串会经历各种替换,而单引号字符串在 shell 中是文字)。

顺便说一句,请注意您可能还想单引号引用 here-doc 分隔符,否则 Python 脚本会受到类似的替换。

python - <<'____HERE'
print("""Look, we can have double quotes!""")
print('And single quotes! And `back ticks`!')
print("$(and what looks to the shell like process substitutions and $variables!)")
____HERE

作为替代方案,如果您愿意,转义分隔符的工作方式相同 (python - &lt;&lt;\____HERE)

【讨论】:

  • 我不明白您关于向外壳返回值的评论。两种构造都打印到标准输出并返回退出代码,如果您愿意,shell 可以检查这两种代码。
  • 同意。您需要为 python 打印到标准输出的输出读取 shell。例如#!/bin/bash function current_datetime { python -
  • 尽管date 命令可能更适合该特定用例。另外,再次引用您的字符串。
  • 您可以使用'\''将单引号“嵌入”到shell中的单引号字符串“内部”。例如。 echo 'Say '\''Hello'\'', Fred'.
  • 是的,这是一个结束单引号,一个未加引号但反斜杠转义的文字单引号,以及单引号字符串其余部分的开始单引号。这对于日常使用来说可能太复杂且难以阅读,但如果您只有其中的一两个,它是可行的。同义,您可以双引号单独的文字单引号 - '"'"';我喜欢称其为“跷跷板式报价”。
【解决方案2】:

如果您更喜欢使用 python -c '...' 而不必使用双引号转义,您可以先使用 here-documents 将代码加载到 bash 变量中:

read -r -d '' CMD << '--END'
print ("'quoted'")
--END
python -c "$CMD"

python 代码被逐字加载到 CMD 变量中,无需转义双引号。

【讨论】:

    【解决方案3】:

    如果你使用 bash,如果你应用更多的样板文件,你可以避免 heredoc 问题:

    python <(cat <<EoF
    
    name = input()
    print(f'hello, {name}!')
    
    EoF
    )
    

    这将让您在不放弃标准输入的情况下运行嵌入式 Python 脚本。开销与使用cmda | cmdb 基本相同。 This technique is known as Process Substitution.

    如果希望能够以某种方式验证脚本,我建议您将其转储到临时文件中:

    #!/bin/bash
    
    temp_file=$(mktemp my_generated_python_script.XXXXXX.py)
    
    cat > $temp_file <<EoF
    # embedded python script
    EoF
    
    python3 $temp_file && rm $temp_file
    

    如果脚本运行失败,这将保留脚本。

    【讨论】:

    • +1 但您应该在完成后删除临时文件。另见stackoverflow.com/questions/687014/…
    • 在上述情况下,如果脚本正常工作,文件将被删除。使用trap 需要一些控制样板,我认为在大多数情况下这是不必要的复杂性。
    • 是的,对于一个临时的 hack 这很好。只是指出如果有人想在生产脚本中执行此操作并不完全明显。
    • 好吧,我在生产中这样做。我使用的额外的东西是 cron 中的 find 对文件的年龄设置了一些限制。当我应用这种技术时,脚本是一个导入和一个函数调用。我认为真正的问题是,当您在 shell 脚本中需要一个简单的业务逻辑并且没有时间或金钱来改进 python 模块时,这种技术应该是一种缓解措施。与此不同的任何事情,例如处理用户输入或公开实际功能,从安全角度来看都是非常危险的。副作用是禁忌,恕我直言;你应该改进模块。
    猜你喜欢
    • 2015-05-29
    • 2016-08-20
    • 2011-01-17
    • 1970-01-01
    • 1970-01-01
    • 2011-10-13
    • 2012-09-08
    • 2021-10-15
    • 1970-01-01
    相关资源
    最近更新 更多