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