2011-08-05 11 views
6

Próbuję określić, w skrypcie Perla w systemie Linux, czy działa w terminalu.Jak sprawdzić, czy skrypt Perl działa w terminalu?

Oznacza to, że muszę kod:

  • zwraca true gdy po prostu działa na linii poleceń
  • zwraca również prawdą, gdy uruchomiony ./myscript.pl | less lub nawet ./myscript.pl </dev/null >/dev/null 2>/dev/null
  • zwraca false gdy uruchomiony w cron albo jako skrypt CGI

Szczególnie z powodu drugiego pocisku nie mogę używać -t STDOUT i odmian, a także IO::Interactive jest bezużyteczny.

Informacja wydaje się być dostępna. Jeśli uruchomię ps, to pojawi się wpis taki jak pts/2 w kolumnie , nawet jeśli uruchomię ./myscript.pl </dev/null >/dev/null 2>/dev/null i ? podczas uruchamiania jako zadanie cron lub skrypt CGI.

Czy istnieje elegancki sposób na określenie tego w skrypcie Perla? Wolałbym nie analizować danych wyjściowych z ps.

+0

Myślę, że perl ma dostępną funkcję 'isatty (3)'. – Keith

+0

'isatty' istnieje w module POSIX, tak, ale, podobnie jak' -t', sprawdza, czy uchwyt pliku jest podłączony do tty. Nie to, czego potrzebuję ... – mscha

+0

Czy dostępna jest funkcja [ctermid] (http://pubs.opengroup.org/onlinepubs/009695399/functions/ctermid.html)? – Keith

Odpowiedz

10

Możesz spróbować otworzyć/dev/tty. To zadziała, jeśli jesteś w terminalu (nawet w terminalu na komputerze zdalnym). W przeciwnym razie, jeśli skrypt zostanie uruchomiony przez at lub cron, nie będzie.

Uwaga: działa to tylko w systemach uniksowych.

+0

Dzięki.Wydaje się, że to wystarczy: 'sub isatty() {no autodie; return open (moje $ tty, '+ <', '/ dev/tty'); } ' – mscha

+0

@mscha - co powiesz na ponowne zamknięcie tego deskryptora pliku - w zależności od tego, jak często to uruchomisz, możesz nie mieć deskryptorów plików. – Ingo

+6

@Ingo, to nie jest konieczne, ponieważ użył leksykalnej uchwytu pliku i nie zwrócił go. Dlatego uchwyt pliku zostanie zamknięty automatycznie, gdy zmienna wykracza poza zakres (gdy 'isatty' zwraca). – cjm

1

PS powinna ci pomóc.
ps aux | grep 'filename.pl'

+2

Dokładnie tego chcę uniknąć ... Również, po prostu przeglądanie nazwy pliku nie jest bardzo wiarygodne. – mscha

0

częściowo odpowiedzieć na moje własne pytanie, co następuje załatwia sprawę:

sub isatty() 
{ 
    my $tty = `/bin/ps -p $$ -o tty --no-headers`; 
    $tty =~ s{[\s?]}{}g; 
    return $tty; 
} 

Zwraca nazwę TTY jeśli (co jest prawdą), lub „”, jeśli żadna (fałsz).

bym nadal preferują rozwiązanie bez zewnętrznego polecenia ...

4

Inną odpowiedzią na moje własne pytanie. Zbadałem źródło ps, aby zobaczyć, jak ustalono TTY i używa ono /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 $1 > 0; 
    } 
    else { 
     die "Unexpected format in /proc/$$/stat"; 
    } 
}