如果我尝试在 bash 脚本中启动 python,该脚本将停止运行,并且在调用“Python”后不会执行任何命令。在这个简单的例子中,“TESTPRINT”将不会被打印。剧本似乎就这样停止了。
#!/bin/bash
python
print("TESTPRINT")
Echo
如何让脚本在进入Python后继续运行?我相信几年前我在编写一个首先需要 shell 到 Android 手机中的脚本后也遇到过同样的问题。我不记得当时是怎么解决的。
答案1
要从脚本运行一组 Python 命令bash
,您必须向 Python 解释器提供要运行的命令,可以从您在脚本中创建的文件(Python 脚本)中执行,如下所示
#!/bin/bash -e
# Create script as "script.py"
cat >script.py <<'END_SCRIPT'
print("TESTPRINT")
END_SCRIPT
# Run script.py
python script.py
rm script.py
(这将创建一个名为的新文件,script.py
如果该文件已存在,则覆盖该文件,然后指示 Python 运行它;然后将其删除)
...或直接通过某种形式的重定向,例如此处文档:
#!/bin/bash
python - <<'END_SCRIPT'
print("TESTPRINT")
END_SCRIPT
它的作用是运行python -
,指示 Python 解释器从标准输入读取脚本。然后,shell 将 Python 脚本的文本(END_SCRIPT
在 shell 脚本中以 分隔)发送到 Python 进程的标准输入流。
请注意,上面的两段代码略有不同,因为第二个脚本的 Python 进程的标准输入连接到它正在读取的脚本,而第一个脚本的 Python 进程可以自由地从标准输入读取脚本以外的数据。如果您的 Python 代码从标准输入读取,这一点很重要。
Python 还可以通过其选项直接从命令行获取一组命令-c
:
#!/bin/bash
python -c 'print("TESTPRINT")'
你什么不能做就是在脚本中间“切换到Python” bash
。
脚本中的命令被bash
一个接一个地执行,并且在执行命令时,脚本本身会等待它终止(如果它不是后台作业)。
这意味着您的原始脚本将以交互模式启动 Python,暂时挂起bash
脚本的执行,直到 Python 进程终止。然后该脚本将尝试print("TESTPRINT")
作为 shell 命令执行。
ssh
在脚本中使用类似的问题:
ssh user@server
cd /tmp
ls
(这可能与您所说的几年前尝试过的类似)。
这个会不是连接到远程系统并在那里运行cd
和ls
命令。它将在远程系统上启动一个交互式 shell,一旦该 shell 终止(将控制权交还给脚本),cd
就会ls
在本地运行。
相反,要在远程计算机上执行命令,请使用
ssh user@server "cd /tmp; ls"
(这是一个蹩脚的例子,但你可能明白了)。
下面的示例显示了您实际上可以如何执行您的建议。但它带有几个警告标签和警告,你永远不应该写这样的代码(因为它很混乱,因此无法维护,而且我敢说,非常糟糕)。
python -
print("TESTPRINT")
运行它:
$ sh -s <script.sh
TESTPRINT
这里发生的情况是脚本正在由 运行sh -s
。选项-s
to sh
(和 to bash
) 告诉 shell 执行通过标准输入流到达的 shell 脚本。
然后脚本开始python -
,它告诉Python运行通过标准输入流传入的任何内容。该流上的下一个内容sh -s
是 Python 命令,因为它是由 Python 继承的(因此连接到我们的脚本文本文件)print("TESTPRINT")
。
然后,Python 解释器将继续从脚本文件读取并执行命令,直到用完或执行 Python 命令exit()
。
答案2
除了 Kusalananda 的答案之外,如果您希望整个脚本由 python 运行,您只需将第一行更改为#!/usr/bin/env python3
并像任何普通 shell 脚本一样运行它。这样您就不必记住必须使用哪个解释器运行哪个脚本。
答案3
您还可以尝试使用<<<
(Here Strings) 运算符来保存行:
$ python <<< 'print("MyTest")'
MyTest
答案4
您还可以在从 bash 脚本调用 python 文件时设置 python 路径:
export PYTHONPATH=/tmp/python_dep.zip && python test_my.py