Task

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

  • [[Check output device is a terminal]]

Ada

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

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;

$ ./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:

#include <unistd.h>
// for isatty()
#include <stdio.h>	//for fileno()

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

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

Common Lisp

(with-open-stream (s *standard-input*)
  (format T "stdin is~:[ not~;~] a terminal~%"
          (interactive-stream-p s)))
$ 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

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

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.");
}
C:\test
Input comes from tty.
C:\test < in.txt
Input doesn't come from tty.

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.")
    }
}

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

Haskell

Example uses [https://hackage.haskell.org/package/unix unix] package:

module Main (main) where

import           System.Posix.IO (stdInput)
import           System.Posix.Terminal (queryTerminal)

main :: IO ()
main = do
    isTTY <- queryTerminal stdInput
    putStrLn $ if isTTY
                then "stdin is TTY"
                else "stdin is not TTY"

Jsish

/* Check input device is a terminal, in Jsish */
;Interp.conf().subOpts.istty;

/*
=!EXPECTSTART!=
Interp.conf().subOpts.istty ==> false
=!EXPECTEND!=
*/
prompt$ jsish
Jsish interactive: see 'help [cmd]' or 'history'.  \ cancels > input.  ctrl-c aborts running script.
jsi> Interp.conf().subOpts.istty;
true
jsi>
prompt$ jsish --U checkInputDevice.jsi
Interp.conf().subOpts.istty ==> false

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


This program sees STDIN as a TTY.

Kotlin

// Kotlin Native version 0.5

import platform.posix.*

fun main(args: Array<String>) {
    if (isatty(STDIN_FILENO) != 0)
        println("stdin is a terminal")
    else
        println("stdin is not a terminal")
}


stdin is 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).




## OCaml



```ocaml
let () =
  print_endline (
    if Unix.isatty Unix.stdin
    then "Input comes from tty."
    else "Input doesn't come from tty."
  )

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

use strict;
use warnings;
use 5.010;
if (-t) {
    say "Input comes from tty.";
}
else {
    say "Input doesn't come from tty.";
}

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

Perl 6

say $*IN.t ?? "Input comes from tty." !! "Input doesn't come from tty.";

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

Pike

void main()
{
    if(Stdio.Terminfo.is_tty())
	write("Input comes from tty.\n");
    else
        write("Input doesn't come from tty.\n");
}
$ ./istty.pike
Input comes from tty.
$ echo | ./istty.pike
Input doesn't come from tty.

Python

from sys import stdin
if stdin.isatty():
    print("Input comes from tty.")
else:
    print("Input doesn't come from tty.")

$ python istty.py Input comes from tty. $ true | python istty.py Input doesn't come from tty.

Racket


(terminal-port? (current-input-port))

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

Ring


# Project  : Check input device is a terminal

load "stdlib.ring"

if isWindows()
   write("mycmd.bat","
   @echo off
    timeout 1 2>nul >nul
    if errorlevel 1 (
       echo input redirected
        ) else (
       echo input is console
       )
       ")
    see SystemCmd("mycmd.bat")
ok

Output:


input redirected

Ruby

Example from the docs.

File.new("testfile").isatty   #=> false
File.new("/dev/tty").isatty   #=> true

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");
    }
}

Scala

import org.fusesource.jansi.internal.CLibrary._

object IsATty  extends App {

  var enabled = true

  def apply(enabled: Boolean): Boolean = {
    // We must be on some unix variant..
    try {
      enabled && isatty(STDIN_FILENO) == 1
    }
    catch {
      case ignore: Throwable =>
        ignore.printStackTrace()
        false

    }
  }

    println("tty " + apply(true))
}

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.

if {[catch {fconfigure stdin -mode}]} {
    puts "Input doesn't come from tty."
} else {
    puts "Input comes from tty."
}

Demonstrating:


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

UNIX Shell

#!/bin/sh

if [ -t 0 ]
then
   echo "Input is a terminal"
else
   echo "Input is NOT a terminal"
fi

zkl

On Unix, check to see if stdin's st_mode is a character device.

const S_IFCHR=0x2000;
fcn S_ISCHR(f){ f.info()[4].bitAnd(S_IFCHR).toBool() }
S_ISCHR(File.stdin).println();

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