Linux 如何检查 Perl 脚本是否在终端中运行?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6955191/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I check if a Perl script is running in a terminal?
提问by mscha
I'm trying to determine, within a Perl script on Linux, whether it's running in a terminal.
我试图在 Linux 上的 Perl 脚本中确定它是否在终端中运行。
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
- 仅在命令行上运行时返回 true
- 运行时
./myscript.pl | less
甚至返回true./myscript.pl </dev/null >/dev/null 2>/dev/null
- 在 cron 作业中运行或作为 CGI 脚本运行时返回 false
Especially because of the second bullet, I can't use -t STDOUT
and variations, and also IO::Interactiveis of no use.
特别是因为第二个子弹,我不能使用-t STDOUT
和变体,而且IO::Interactive也没有用。
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.
该信息似乎是可用的。如果我运行ps
,它会pts/2
在TTY
列中显示一个条目,即使我运行时./myscript.pl </dev/null >/dev/null 2>/dev/null
,以及?
作为 cron 作业或 CGI 脚本运行时也是如此。
Is there an elegant way to determine this in a Perl script? I'd rather not have to parse the output of ps
.
在 Perl 脚本中是否有一种优雅的方法来确定这一点?我宁愿不必解析ps
.
采纳答案by Ingo
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.
您可以尝试打开/dev/tty。如果您在终端中(甚至在远程计算机上的终端中),这将起作用。否则,如果脚本通过 at 或 cron 运行,则不会。
Note: this will only work on Unix systems.
注意:这仅适用于 Unix 系统。
回答by Kracekumar
PS should help you out.ps aux | grep 'filename.pl'
PS应该可以帮助你。ps aux | grep 'filename.pl'
回答by mscha
To partially answer my own question, the following does the trick:
为了部分回答我自己的问题,以下是诀窍:
sub isatty()
{
my $tty = `/bin/ps -p $$ -o tty --no-headers`;
$tty =~ s{[\s?]}{}g;
return $tty;
}
Returns the TTY name if any (which is true), or "" if none (false).
返回 TTY 名称(如果有)(这是真的),或者“”如果没有(假)。
I'd still prefer a solution without an external command...
我仍然更喜欢没有外部命令的解决方案......
回答by mscha
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
源代码,看看它是如何确定 TTY 的,它使用/proc/[pid]/stat
.
use strict;
use warnings;
use 5.010;
use autodie;
sub isatty()
{
# See http://www.kernel.org/doc/man-pages/online/pages/man5/proc.5.html
open(my $stat, '<', "/proc/$$/stat");
if (<$stat> =~ m{^\d+\s+\(.*\)\s+\w\s+\d+\s+\d+\s+\d+\s+(\d+)}) {
return > 0;
}
else {
die "Unexpected format in /proc/$$/stat";
}
}
回答by Znik
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.
首先,您必须检查,输出通过 -t 与终端相关联。当然,如果你愿意,你可以查看 /proc/$pid/fd/1 ,它是设备的符号链接。你可以测试它,如果它是一个终端。
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.
但如果还不够,可以通过%ENV 特殊哈希表检查环境变量。CGI-BIN 接口设置了其中的一些。如果您在 cron 下运行脚本,它会设置一些变量。如果还不够,你可以在 /etc/crontab 文件中设置并在你的脚本中测试。你要做的就是满足你的需要。
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.
您不必调用任何外部命令,或者您不需要特殊的 libarier。只有你需要的是 Windows 不兼容。但是如果你使用的是windows10,那么它的环境类似于基于ubuntu的linux。那么你就不能像这样做那样在 win32api 和类似 Unix 的系统之间保持兼容性。