我想在Bash脚本中运行一些Python代码,因此我想了解以下两者之间的区别:
#!/bin/bash
#your bash code
python -c "
#your py code
"
对抗
python - <<DOC
#your py code
DOC
我查阅了网页,但无法整合与该主题相关的信息。您认为哪个更好?如果您想从Python代码块返回值到Bash脚本中,那么heredoc是唯一的选择吗?
我想在Bash脚本中运行一些Python代码,因此我想了解以下两者之间的区别:
#!/bin/bash
#your bash code
python -c "
#your py code
"
对抗
python - <<DOC
#your py code
DOC
我查阅了网页,但无法整合与该主题相关的信息。您认为哪个更好?如果您想从Python代码块返回值到Bash脚本中,那么heredoc是唯一的选择吗?
python -c
几乎是你唯一的选择。python -c '...'
会占用单引号,因此你只能在Python脚本中使用双引号字符串;如果使用双引号来保护脚本免受shell的影响,会引入额外的问题(双引号字符串会经历各种替换,而单引号字符串在shell中是字面的)。python - <<'____HERE'
print("""Look, we can have double quotes!""")
print('And single quotes! And `back ticks`!')
print("$(and what looks to the shell like command substitutions and $variables!)")
____HERE
python - <<\____HERE
)。#!/bin/bash
function current_datetime {
python - <<'__COB'
import datetime
print datetime.datetime.now()
__COB
}
dtm=$(current_datetime)
echo 当前日期和时间:$dtm
- Kashifdate
命令可能更适合那个特定的用例。同样,再次引用您的字符串。 - tripleee'\''
来“嵌入”单引号。例如:echo 'Say '\''Hello'\'', Fred'
。 - jrw32982'"'"'
;我喜欢称之为“跷跷板引用”。 - tripleee如果您正在使用bash,可以通过应用更多的样板代码来避免heredoc问题:
python <(cat <<EoF
name = input()
print(f'hello, {name}!')
EoF
)
使用这种技术,您可以在不放弃标准输入的情况下运行嵌入的Python脚本。其开销与使用 cmda | cmdb
基本相同。 这种技术称为进程替换。
如果希望能够验证脚本,建议将其转储到临时文件中:
#!/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
如果脚本无法运行,这将保留脚本。
find
命令来设置文件年龄的限制。当我应用这种技术时,脚本是一个导入和函数调用。我认为真正的问题是,这种技术应该是一种缓解措施,用于当您需要在shell脚本中使用简单业务逻辑但没有时间或金钱来改进Python模块时。任何与此不同的操作,例如处理用户输入或公开实际功能,从安全角度来看都非常危险。副作用是不可取的,在我看来;您应该改进模块。 - PEdroArthur如果您想使用python -c '...'
而不必使用双引号进行转义,您可以使用here-documents首先将代码加载到bash变量中:
read -r -d '' CMD << '--END'
print ("'quoted'")
--END
python -c "$CMD"
Python代码会原样加载到CMD变量中,不需要转义双引号。
tripleee的答案中有所有细节,但是有Unix技巧可以解决这个限制:
因此,如果您有一个想要处理其标准输入的脚本,则
python -c
基本上是您唯一的选择。
这个技巧适用于所有希望从重定向的stdin(例如,./script.py < myinputs
)读取并同时接受用户输入的程序:
python - <<'____HERE'
import os
os.dup2(1, 0)
print(input("--> "))
____HERE
运行这个是有效的:
$ bash heredocpy.sh
--> Hello World!
Hello World!
os.dup(0)
。这里 是一个真实世界的例子。
cat <<'____HERE' > file.txt
With software there are only two possibilites:
either the users control the programme
or the programme controls the users.
____HERE
python - <<'____HERE' 4< file.txt
import os
for line in os.fdopen(4):
print(line.rstrip().upper())
____HERE
不幸的是,管道在这里不起作用 -- 但进程替换可以:
python - <<'____HERE' 4< <(fortune)
import os
for line in os.fdopen(4):
print(line.rstrip().upper())
____HERE