python - 知道 python 脚本在由 crontab 启动时可以从标准输入中读取一些内容
问题描述
我有一个由 crontab 运行的 python 脚本,可以手动执行。
该脚本作为输入:
- 来自
-i
参数的值, - 或任何来自
stdin
.pipe
代码应该是这样的:
if ???: #test to check if there is some data in stdin
print("I have data from stdin!")
else:
print("I have no data from stdin!")
脚本执行如下:
$ ./myscript.py -i myInput
> I have no data from stdin!
$ cat myInput | ./myscript.py
> I have data from stdin!
我尝试了几种在通过控制台执行时可以正常工作的方法,但在通过 crontab 执行时不能按预期工作:脚本始终认为有来自标准输入的数据。
第一次测试:
if not sys.stdin.isatty():
print("I have data from stdin!")
else:
print("I have no data from stdin!")
我认为这个不起作用,因为在 crontab 模式下没有 tty,所以第一个语句总是正确的。
第二次测试:
import stat
mode = os.fstat(sys.stdin.fileno()).st_mode
if stat.S_ISFIFO(mode):
print("I have data from stdin!")
else:
print("I have no data from stdin!")
第三次测试:
import select
r, w, x = select.select([sys.stdin], [], [], 0)
if r:
print("I have data from stdin!")
else:
print("I have no data from stdin!")
有没有正确的方法让它同时适用于控制台和 crontab 模式?
解决方案
正如 Nullman 已经在评论中所写,最好检查您的命令行选项以决定是否要尝试stdin
。
简短摘要:您无法安全地猜测是否应该stdin
通过检查来读取数据stdin
。您应该只依靠检查命令行来找出预期的内容。
例如,仅当没有将输入文件指定为命令行参数或指定了特殊文件名时cat
才会使用。stdin
-
您示例中的所有测试仅在某些条件下有效,而在其他情况下无效。
检查是否stdin
是 TTY 没有帮助。它只会告诉您它是否连接到终端。如果用户键入某些内容或者它是连接到其他内容的伪终端,您的脚本可以从终端获取输入。stdin
如果您的脚本没有连接到终端,而是连接到其他东西(管道、文件、套接字......),您的脚本也可以从中获取输入
检查是否stdin
是 FIFO 也是错误的,因为您可以从管道/fifo 或其他东西(文件、套接字、终端......)读取数据。
usingselect
不会告诉你是否有任何数据,但只会告诉你 aread
不会阻塞。它也不会阻塞 EOF。要区分这些情况,您必须检查 a read
from的结果stdin
。如果没有延迟/超时,它也可能会告诉您read
如果数据尚不可用 a 将阻塞。
还有更多使用脚本的方法:
而不是cat myInput | ./myscript.py
你也可以使用./myscript.py < myInput
. 在第一种情况下stdin
是一个管道,在第二种情况下是一个文件。
或者想象一下./myscript.py < /dev/null
。这将在第一个返回 EOF 条件read
。
或者当您尝试从中读取时./myscript.py <&-
会关闭stdin
导致错误。
如果stdin
连接到终端,read
如果用户不输入任何内容,则可能会阻塞。如果您调用./myscript.py
. 您可以使用select
来确定数据是否现在可用,但您无法确定用户稍后是否会输入数据。所以你的脚本不知道用户的意图。
推荐阅读
- raspberry-pi - 如何在树莓派等边缘设备中加载或推断 onnx 模型?
- node.js - 如何在 Heroku 上运行 redis?
- kotlin - 何时为类中的协程指定 Dispatchers.xxx
- sql - 带有 NEW 的 JPQL 请求花费了太多时间
- javascript - 如何在 JS 中为前 2 个字符编写正则表达式,可以是数字或字母,后跟连字符,然后是 6 位数字?
- android - 缩小应用程序时,Android PDF 查看器崩溃
- flutter - 长按 EditableText 小部件时不显示文本选择工具栏选项
- sql - SQL获取共享外键的所有行
- bash - 我可以找到哪个用户使用 sudo 来运行我的脚本吗?
- docusignapi - Docusign - 历史(通过第三方应用程序)