知道python脚本在crontab启动时可以从stdin读取

问题描述 投票:0回答:1

我有一个由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执行时没有按预期工作:脚本始终认为来自stdin的IS数据。

第一次测试:

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模式?

python linux python-3.x cron stdin
1个回答
2
投票

正如Nullman已在评论中写道,最好检查一下命令行选项,以决定是否要尝试使用stdin

简短摘要:您无法安全地猜测是否应该通过检查stdin来读取stdin的数据。您应该只依靠检查命令行来找出预期的内容。

例如,仅当没有将输入文件指定为命令行参数或者指定了特殊文件名cat时,stdin才会使用-


您的示例中的所有测试仅在某些条件下有效,在其他情况下不起作用。

检查stdin是否是TTY没有帮助。它只会告诉您它是否连接到终端。如果用户键入内容或者是连接到其他内容的伪终端,您的脚本可以从终端获取输入。你的脚本也可以从stdin获得输入,如果它没有连接到终端而是连接到其他东西(管道,文件,套接字......)

检查stdin是否是FIFO也是错误的,因为你可以从pipe / fifo或其他东西(文件,套接字,终端......)读取数据。

使用select不会告诉您是否有任何数据,但仅限于read不会阻止。它也不会阻止EOF。要区分这些情况,您必须检查来自readstdin的结果。如果没有延迟/超时,它也可能会告诉您,如果数据尚未可用,read将会阻止。

有更多方法可以使用该脚本:

而不是cat myInput | ./myscript.py你也可以使用./myscript.py < myInput。在第一种情况下,stdin将是一个管道,在第二种情况下是一个文件。

或者想象./myscript.py < /dev/null。这将返回第一个read的EOF条件。 或./myscript.py <&-将关闭stdin导致错误,当你尝试从它读取。

如果stdin连接到终端,如果用户没有输入任何内容,read可能会阻止。如果你打电话给./myscript.py,就会发生这种情况。您可以使用select查看数据是否现在可用,但您无法确定用户是否稍后会输入数据。所以你的脚本不知道用户的意图。

© www.soinside.com 2019 - 2024. All rights reserved.