Check input device is a terminal

From Rosetta Code
Revision as of 18:52, 25 August 2016 by rosettacode>Gerard Schildberger (added whitespace before the TOC (table of contents), added a ;Task: (bold) header.)
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.
Task

Demonstrate how to check whether the input device is a terminal or not.


Related task



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.

Julia

<lang Julia> if isa(STDIN, Base.TTY)

   println("This program sees STDIN as a TTY.")

else

   println("This program does not see STDIN as a TTY.")

end </lang>

Output:
This program sees STDIN as a TTY.

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

Works with: Rakudo version 2015.12

<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.

Pike

<lang pike>void main() {

   if(Stdio.Terminfo.is_tty())

write("Input comes from tty.\n");

   else
       write("Input doesn't come from tty.\n");

}</lang>

Output:
$ ./istty.pike
Input comes from tty.
$ echo | ./istty.pike
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.py
Input comes from tty.
$ true | python istty.py
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>/* Uses C library interface */

extern crate libc;

fn main() {

   let istty = unsafe { libc::isatty(libc::STDIN_FILENO as i32) } != 0;
   if istty {
       println!("stdout is tty");
   } else {
       println!("stdout 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>

zkl

On Unix, check to see if stdin's st_mode is a character device. <lang zkl>const S_IFCHR=0x2000; fcn S_ISCHR(f){ f.info()[4].bitAnd(S_IFCHR).toBool() } S_ISCHR(File.stdin).println();</lang>

Output:
$ zkl bbb  # from the command line
True
$ zkl bbb < bbb.zkl
False
$ cat bbb.zkl | zkl bbb
False