抱歉,标题可能不太清楚。这是我的疑问的完整解释。我正在编写下面的 shell 脚本并期待提到的输出。
#!/bin/bash
python3
print("Hello World")
exit()
echo "The execution is completed"
我期望的输出是,它应该进入 python3 解释器并执行print
和exit()
命令,并且在执行exit()
命令后,如果我们手动执行解释器退出,然后执行命令。但执行echo
后它不会那样工作python3
正在进入 python3 解释器但不执行print
和exit()
。
>>>
它正确输入 python3,然后停在那里,直到我手动退出 python 解释器。
我应该做出哪些改变才能获得预期的输出。
- 后续问题:是否可以将
Hello world
python 解释器中生成的输出或任何其他输出获取到 bash 环境并在 bash 脚本中使用它。 2.您指定运行python命令的方法也适用于其他工具吗?
答案1
#!/bin/bash python3 print("Hello World") exit() echo "The execution is completed"
脚本的工作方式与直接在终端中键入命令不同,即。你想做的事情不会这么容易实现。
该#!/bin/bash
行告诉内核它尝试启动的程序是一个需要使用/bin/bash
.因此,当您运行./scriptname
内核时,bash 将从标准输入(终端)而不是标准输入中/bin/bash ./scriptname
读取命令。scriptname
当 bash 到达该python
行时,它将启动 Python 解释器并等待其退出,然后再继续下一行。当 Python 启动时,它会执行与python
在终端中键入时相同的操作,它将启动交互式解释器。
Python 不知道您想要从脚本文件运行命令,并且您也无法告诉它跳过几行。
当Python退出时,bash将从下一行继续,quit()
这是一个语法错误,你也不能告诉Bash跳过后面的几行python
。
可以通过三种方式让Python运行命令:
- 让 bash 通过定界文档 (*1) 将命令写入 python 的输入。如果这样做,Python 将无法从终端读取用户输入。
- 使用该
-c
选项提供简短的命令列表。这仅适用于非常短的程序,也不需要使用任何引号(对于字符串)。多个命令可以用分号分隔。 - 有一个单独的 Python 脚本,这需要第二个文件。如果您了解与临时文件 (*2) 相关的安全风险,您可以根据需要让 bash 为您创建该文件。只要不要创建文件
/tmp
就可以了。
后续问题:是否可以将输出 Hello world 或 python 解释器中生成的任何其他输出获取到 bash 环境并在 bash 脚本中使用它。
您可以使用$(
和来使用命令替换)
,请在双引号字符串内使用它们。您甚至可以在内部嵌套双引号字符串:
test="$(python -c "import sys; print(sys.version)")"
echo "Python has finished"
echo "test = $test"
您指定运行 python 命令的方法也适用于其他工具吗?
上面列出的所有三种方法也适用于许多其他脚本语言。
*1 Heredoc 示例
read -p "How many numbers: " n
python <<END
for i in range($n):
print(i)
print("Literal dollar sign \$")
END
该<<END
语法使 shell (bash) 读取所有行,直到读取单词END
。请注意,END
必须位于行的开头。
这样你就不需要转义引号。 shell 仍然会解释美元符号,因此您可以使用变量。如果你想要一个真正的美元符号,你需要像这样转义它\$
。
*2 临时文件的危险示例。请勿使用此代码
cat >/tmp/python-script <<END
for i in range(10):
print(i)
END
python /tmp/python-script
如果其他人/tmp/python-script
先创建,则该 shell 脚本如果无法覆盖该文件,甚至不会停止。系统上的恶意用户可能会创建有害的 Python 脚本,该脚本将代替预期的脚本运行。
这并不是唯一可能出错的事情。
有多种方法可以安全地执行此操作,但最简单的方法是在当前工作目录或主目录中的专用目录中创建文件。
cat >dopythonstuff <<END
...
END
python dopythonstuff
rm dopythonstuff
答案2
使用 Python 启动 bash 脚本并将变量传递给 bash 脚本:
将 python 变量值传输到 bash 脚本(在 python 脚本内)
关于如何从 Python 脚本调用 shell 命令的 Stack Overflow 问题有 62 个答案:
https://stackoverflow.com/questions/89228/how-to-call-an-external-command
Python 无法退出然后调用 shell 命令。退出 Python 脚本之前必须调用 shell 命令。
https://www.geeksforgeeks.org/python-exit-commands-quit-exit-sys-exit-and-os-_exit/
上面链接下的这篇文章介绍了如何使用各种命令退出 Python:
函数 quit()、exit()、sys.exit() 和 os._exit() 具有几乎相同的功能,因为它们引发 SystemExit 异常,Python 解释器通过该异常退出并且不打印堆栈回溯。我们可以捕获异常来拦截早期退出并执行清理活动;如果未捕获,解释器将照常退出。
文章最后总结道:
在上述四个退出函数中,sys.exit() 是首选,因为 exit() 和 quit() 函数不能在生产代码中使用,而 os._exit() 仅适用于需要立即退出的特殊情况。
您可以使用 sys.exit("Exit message here") 退出 Python 脚本并将退出消息写入控制台,然后控制台返回到 shell 提示符。