Check input device is a terminal

From Rosetta Code
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[edit]

Works with: GNAT

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;
Output:
$ ./test_tty 
stdin is a tty.
$ ./test_tty < /dev/null
stdin is not a tty.

C[edit]

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;
}
Output:
$ ./a.out
stdin is tty
$ ./a.out < /dev/zero
stdin is not tty
$ echo "" | ./a.out
stdin is not tty

Common Lisp[edit]

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

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

D[edit]

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

Go[edit]

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.")
}
}
Output:
> hello
Hello terminal
> hello </dev/null
Who are you?  You're not a terminal.

Julia[edit]

 
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
 
Output:
This program sees STDIN as a TTY.

Kotlin[edit]

Works with: Ubuntu version 14.04
// Kotlin Native version 0.2
 
import unistd.*
 
fun main(args: Array<String>) {
if (isatty(STDIN_FILENO) != 0)
println("stdin is a terminal")
else
println("stdin is not a terminal")
}
 
Output:
stdin is a terminal

Nemerle[edit]

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

def isTerm = System.Console.IsInputRedirected;

OCaml[edit]

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[edit]

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[edit]

Works with: Rakudo version 2015.12
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[edit]

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

Python[edit]

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[edit]

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

REXX[edit]

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

Ruby[edit]

Example from the docs.

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

Rust[edit]

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

Tcl[edit]

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[edit]

#!/bin/sh
 
if [ -t 0 ]
then
echo "Input is a terminal"
else
echo "Input is NOT a terminal"
fi

zkl[edit]

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();
Output:
$ zkl bbb  # from the command line
True
$ zkl bbb < bbb.zkl
False
$ cat bbb.zkl | zkl bbb
False