如何检查 Perl 脚本是否正在终端中运行?
我试图在 Linux 上的 Perl 脚本中确定它是否在终端中运行。
也就是说,我需要的代码:
- 仅在命令行上运行时返回 true
- 运行
./myscript.pl | 时也返回 true less
甚至./myscript.pl /dev/null 2>/dev/null
- 在 cron 作业中运行或作为 CGI 运行时返回 false 特别是因为第二个项目符号
,我无法使用 -t STDOUT
和变体,而且 IO::Interactive 没有用。
该信息似乎确实可用。如果我运行 ps
,它会在 TTY
列中显示类似 pts/2
的条目,即使我运行 ./myscript 也是如此。 pl /dev/null 2>/dev/null
和 ?
作为 cron 作业或 CGI 脚本运行时。
有没有一种优雅的方法可以在 Perl 脚本中确定这一点?我不想解析 ps 的输出。
I'm trying to determine, within a Perl script on Linux, whether it's running in a terminal.
That is, I need code that:
- returns true when simply running on the command-line
- also returns true when running
./myscript.pl | less
or even./myscript.pl </dev/null >/dev/null 2>/dev/null
- returns false when running in a cron job, or as a CGI script
Especially because of the second bullet, I can't use -t STDOUT
and variations, and also IO::Interactive is of no use.
The information does appear to be available. If I run ps
, it shows an entry like pts/2
in the TTY
column, even when I run ./myscript.pl </dev/null >/dev/null 2>/dev/null
, and ?
when running as a cron job or CGI script.
Is there an elegant way to determine this in a Perl script? I'd rather not have to parse the output of ps
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
你可以尝试打开/dev/tty。
如果您在终端中(甚至在远程计算机上的终端中),这将起作用。
否则,如果脚本通过 at 或 cron 运行,则不会。
注意:这仅适用于 Unix 系统。
You can try to open /dev/tty.
This will work if you are in a terminal (even in a terminal on a remote computer).
Otherwise, if the script is run via at or cron, it won't.
Note: this will only work on Unix systems.
我自己的问题的另一个答案。我研究了
ps
源代码,了解它如何确定 TTY,它使用/proc/[pid]/stat
。Another answer to my own question. I studied the
ps
source to see how it determined the TTY, and it uses/proc/[pid]/stat
.PS 应该可以帮助你。
PS 辅助 | grep '文件名.pl'
PS should help you out.
ps aux | grep 'filename.pl'
为了部分回答我自己的问题,以下方法可以解决问题:
如果有的话返回 TTY 名称(为真),如果没有则返回“”(假)。
我仍然更喜欢没有外部命令的解决方案......
To partially answer my own question, the following does the trick:
Returns the TTY name if any (which is true), or "" if none (false).
I'd still prefer a solution without an external command...
首先,您必须检查输出是否通过 -t 与终端关联。当然,如果你愿意,你可以查看 /proc/$pid/fd/1 ,它是设备的符号链接。如果是终端的话你可以测试一下。
但如果还不够,你可以通过%ENV特殊哈希表来检查环境变量。 CGI-BIN 接口设置了其中一些。如果您在 cron 下运行脚本,它会设置一些变量。如果还不够,您可以在 /etc/crontab 文件中设置它并在脚本中进行测试。你要做的就是为了你的需要。
您应该只调用该完整过程一次。您无法迭代它,因为脚本环境不会改变,直到它开始工作。
您不必调用任何外部命令,也不需要特殊的 libarier。您所需要的只是 Windows 不兼容。但如果你使用的是windows10,那么它有类似于基于ubuntu的linux的环境。那么你就不能像你这样做那样强烈地关注win32api和类unix系统之间的兼容性。
At first you must check, output is associated with terminal by -t . Of course if you want, you can look at /proc/$pid/fd/1 , it is symlink to device. You can test it, if it is a terminal.
But if it is not enough, you can check enviromential variables by %ENV special hash table. CGI-BIN interface sets some of them. If you run script under cron, it sets some variable. If it is not enough, you can set it in /etc/crontab file and test in your script. It is for your needs what you'll do.
You should call that complete procedure only once. You cannot iterate it, because script environment won't change, until it is working.
You don't have to call any external commands, or you don't need special libarier. Only what you need, is windows incompatibilities. But if you are using windows10, then it has environment similar to linux based on ubuntu. then you cannot look out as strongly, as you do it making compatibility between win32api and unix like systems.