Check input device is a terminal

From Rosetta Code
Revision as of 00:33, 7 November 2014 by rosettacode>Hajo (moved Categorys to top)
Check input device is a terminal is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

The task is to demonstrate how to check whether the input device is a terminal or not.

See also: Check output device is a terminal

Ada

Works with: GNAT

We use the interface to C library functions isatty() and fileno().

<lang ada>with Ada.Text_IO; use Ada.Text_IO; with Interfaces.C_Streams; use Interfaces.C_Streams;

procedure Test_tty is begin

  if Isatty(Fileno(Stdin)) = 0 then
     Put_Line(Standard_Error, "stdin is not a tty.");
  else
     Put_Line(Standard_Error, "stdin is a tty.");
  end if;

end Test_tty;</lang>

Output:
$ ./test_tty 
stdin is a tty.
$ ./test_tty < /dev/null
stdin is not a tty.

C

Use isatty() on file descriptor to determine if it's a TTY. To get the file descriptor from a FILE* pointer, use fileno: <lang c>#include <unistd.h> //for isatty()

  1. include <stdio.h> //for fileno()

int main(void) { puts(isatty(fileno(stdin)) ? "stdin is tty" : "stdin is not tty"); return 0; }</lang>

Output:
$ ./a.out
stdin is tty
$ ./a.out < /dev/zero
stdin is not tty
$ echo "" | ./a.out
stdin is not tty

Common Lisp

Works with: SBCL

<lang lisp>(with-open-stream (s *standard-input*)

 (format T "stdin is~:[ not~;~] a terminal~%" 
         (interactive-stream-p s)))</lang>
Output:
$ sbcl --script rc.lisp
stdin is a terminal
$ sbcl --script rc.lisp < /dev/zero
stdin is not a terminal
$ echo "" | sbcl --script rc.lisp
stdin is not a terminal

Crystal

<lang ruby>File.new("testfile").tty? #=> false File.new("/dev/tty").tty? #=> true STDIN.tty? #=> true</lang>

D

<lang d>import std.stdio;

extern(C) int isatty(int);

void main() {

   if (isatty(0))
       writeln("Input comes from tty.");
   else
       writeln("Input doesn't come from tty.");

}</lang>

Output:
C:\test
Input comes from tty.
C:\test < in.txt
Input doesn't come from tty.

Go

<lang go>package main

import (

   "golang.org/x/crypto/ssh/terminal"
   "fmt"
   "os"

)

func main() {

   if terminal.IsTerminal(int(os.Stdin.Fd())) {
       fmt.Println("Hello terminal")
   } else {
       fmt.Println("Who are you?  You're not a terminal.")
   }

}</lang>

Output:
> hello
Hello terminal
> hello </dev/null
Who are you?  You're not a terminal.

Nemerle

There is no explicit way (ie isatty())to do this; however, if we assume that standard input is a terminal, we can check if the input stream has been redirected (presumably to something other than a terminal). <lang Nemerle>def isTerm = System.Console.IsInputRedirected;</lang>

OCaml

<lang ocaml>let () =

 print_endline (
   if Unix.isatty Unix.stdin
   then "Input comes from tty."
   else "Input doesn't come from tty."
 )</lang>

Testing in interpreted mode:

$ ocaml unix.cma istty.ml
Input comes from tty.
$ echo "foo" | ocaml unix.cma istty.ml
Input doesn't come from tty.

Perl

<lang perl>use strict; use warnings; use 5.010; if (-t) {

   say "Input comes from tty.";

} else {

   say "Input doesn't come from tty.";

}</lang>

$ perl istty.pl
Input comes from tty.
$ true | perl istty.pl
Input doesn't come from tty.

Perl 6

<lang perl6>say $*IN.t ?? "Input comes from tty." !! "Input doesn't come from tty.";</lang>

$ perl6 istty.p6
Input comes from tty.
$ true | perl6 istty.p6
Input doesn't come from tty.

Python

<lang python>from sys import stdin if stdin.isatty():

   print("Input comes from tty.")

else:

   print("Input doesn't come from tty.")</lang>
$ python istty.pl
Input comes from tty.
$ true | python istty.pl
Input doesn't come from tty.

Racket

<lang racket> (terminal-port? (current-input-port)) </lang>

REXX

<lang rexx>/*REXX program determines if input comes from terminal or standard input*/

if queued() then say 'input comes from the terminal.'

            else say 'input comes from the (stacked) terminal queue.'
                                      /*stick a fork in it, we're done.*/

</lang>

Ruby

Example from the docs. <lang ruby>File.new("testfile").isatty #=> false File.new("/dev/tty").isatty #=> true</lang>

Rust

<lang rust>/*Rust 0.9 version. Uses C library interface*/ extern mod std; use std::libc;

fn main() {

   let istty = unsafe { libc::isatty(libc::STDIN_FILENO as i32) } != 0;
   if (istty) {
       println("stdin is tty");
   } else {
       println("stdin is not tty");
   }

}</lang>

Tcl

Tcl automatically detects whether stdin is coming from a terminal (or a socket) and sets up the channel to have the correct type. One of the configuration options of a terminal channel is -mode (used to configure baud rates on a real serial terminal) so we simply detect whether the option is present. <lang tcl>if {[catch {fconfigure stdin -mode}]} {

   puts "Input doesn't come from tty."

} else {

   puts "Input comes from tty."

}</lang> Demonstrating:

$ tclsh8.5 istty.tcl 
Input comes from tty.
$ tclsh8.5 istty.tcl </dev/null
Input doesn't come from tty.

UNIX Shell

<lang sh>#!/bin/sh

if [ -t 0 ] then

  echo "Input is a terminal"

else

  echo "Input is NOT a terminal"

fi</lang>