Check input device is a terminal
You are encouraged to solve this task according to the task description, using any language you may know.
- Task
Demonstrate how to check whether the input device is a terminal or not.
- Related task
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;
- Output:
$ ./test_tty stdin is a tty. $ ./test_tty < /dev/null stdin is not a tty.
BASIC
BaCon
terminal = isatty(0)
PRINT terminal
- Output:
prompt$ bacon -q istty.bac Converting 'istty.bac'... done, 4 lines were processed in 0.002 seconds. Compiling 'istty.bac'... cc -c istty.bac.c cc -o istty istty.bac.o -lm Done, program 'istty' ready. prompt$ ./istty 1 prompt$ ./istty <<<"testing" 0
FreeBASIC
Open Cons For Input As #1
' Open Cons abre los flujos de entrada (stdin) o salida (stdout) estándar
' de la consola para leer o escribir.
If Err Then
Print "Input doesn't come from tt."
Else
Print "Input comes from tty."
End If
Close #1
Sleep
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;
}
- Output:
$ ./a.out stdin is tty $ ./a.out < /dev/zero stdin is not tty $ echo "" | ./a.out stdin is not tty
COBOL
Works with GnuCOBOL.
*>
*> istty, check id fd 0 is a tty
*> Tectonics: cobc -xj istty.cob
*> echo "test" | ./istty
*>
identification division.
program-id. istty.
data division.
working-storage section.
01 rc usage binary-long.
procedure division.
sample-main.
call "isatty" using by value 0 returning rc
display "fd 0 tty: " rc
call "isatty" using by value 1 returning rc
display "fd 1 tty: " rc upon syserr
call "isatty" using by value 2 returning rc
display "fd 2 tty: " rc
goback.
end program istty.
DISPLAY for fd 1 is directed to SYSERR to get some output during the various trials.
- Output:
prompt$ cobc -xj istty.cob fd 0 tty: +0000000001 fd 1 tty: +0000000001 fd 2 tty: +0000000001 prompt$ echo "test" | ./istty fd 0 tty: +0000000000 fd 1 tty: +0000000001 fd 2 tty: +0000000001 prompt$ echo "test" | ./istty >/dev/null fd 1 tty: +0000000000 prompt$ echo "test" | ./istty 2>/dev/tty fd 0 tty: +0000000000 fd 1 tty: +0000000001 fd 2 tty: +0000000001 prompt$ echo "test" | ./istty 2>/dev/null fd 0 tty: +0000000000 fd 2 tty: +0000000000
Common Lisp
(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
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.");
}
- Output:
C:\test Input comes from tty. C:\test < in.txt Input doesn't come from tty.
ed
Givent that ed is a non-graphical editor that's almost exclusively run in terminal, the program only needs to highlight this fact.
# by Artyom Bologov
H
a
Input from terminal!
.
p
Q
Forth
In Gforth, the word "source-id" is used to determine the program source.
If you got a program file "source.f":
: ?tty source-id if ." not " then ." from terminal" ; ?tty bye
Then,
gforth source.f
in the shell will display:
- Output:
not from terminal
Then,
gforth -e ': ?tty source-id if ." not " then ." from terminal" ; ?tty bye'
will display:
- Output:
not from terminal
At Gforth prompt,
: ?tty source-id if ." not " then ." from terminal" ; ?tty bye
will display:
- Output:
from terminal
FutureBasic
include "NSLog.incl"
BeginCCode
if (isatty(fileno(stdin)))
NSLog( @"stdin is connected to a terminal" );
else
NSLog( @"stdin is NOT connected to a terminal" );
EndC
HandleEvents
- Output:
stdin is NOT connected to a terminal
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.")
}
}
- Output:
> hello Hello terminal > hello </dev/null Who are you? You're not a terminal.
Haskell
Example uses 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!=
*/
- Output:
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
- Output:
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")
}
- Output:
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).
def isTerm = System.Console.IsInputRedirected;
Nim
Using function "isatty" of standard module "terminal" which accepts a File as argument.
import terminal
echo if stdin.isatty: "stdin is a terminal" else: "stdin is not a terminal"
- Output:
Command: ./check_input_dev Result: stdin is a terminal
Command: ./check_input_dev <somefile Result: stdin is not a terminal
Nu
$'stdin is a terminal: (is-terminal -i)'
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.
Ol
(define (isatty? fd) (syscall 16 fd 19))
(print (if (isatty? stdin)
"Input comes from tty."
"Input doesn't come from tty."))
PascalABC.NET
##
uses system;
system.Console.IsInputRedirected.println;
- Output:
C:\PABCWork.NET\Output>checkinput.exe False C:\PABCWork.NET\Output>echo test | checkinput.exe True
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.
Phix
without js -- (no input redirection in a browser!) printf(1,"stdin:%t, stdout:%t, stderr:%t\n",{isatty(0),isatty(1),isatty(2)})
- Output:
C:\Program Files (x86)\Phix>p test stdin:true, stdout:true, stderr:true C:\Program Files (x86)\Phix>echo hello | p test stdin:false, stdout:true, stderr:true
Pike
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
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.
Quackery
[ $ |from sys import stdin
to_stack( 1 if stdin.isatty() else 0)|
python ] is ttyin ( --> b )
ttyin if
[ say "Looks like a teletype." ]
else
[ say "Not a teletype." ]
- Output:
Looks like a teletype.
Racket
(terminal-port? (current-input-port))
Raku
(formerly Perl 6)
say $*IN.t ?? "Input comes from tty." !! "Input doesn't come from tty.";
$ raku istty.raku Input comes from tty. $ true | raku istty.raku Input doesn't come from tty.
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))
}
Standard ML
val stdinRefersToTerminal : bool = Posix.ProcEnv.isatty Posix.FileSys.stdin
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
Wren
import "io" for Stdin
System.print("Input device is a terminal? %(Stdin.isTerminal ? "Yes" : "No")")
- Output:
Input device is a terminal? Yes
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();
- Output:
$ zkl bbb # from the command line True $ zkl bbb < bbb.zkl False $ cat bbb.zkl | zkl bbb False
- Terminal control
- Hardware
- Initialization
- Programming Tasks
- Solutions by Programming Task
- Ada
- BASIC
- BaCon
- FreeBASIC
- C
- COBOL
- Common Lisp
- Crystal
- D
- Ed
- Forth
- FutureBasic
- Go
- Go sub-repositories
- Haskell
- Jsish
- Julia
- Kotlin
- Nemerle
- Nim
- Nu
- OCaml
- Ol
- PascalABC.NET
- Perl
- Phix
- Pike
- Python
- Quackery
- Racket
- Raku
- REXX
- Ring
- Ruby
- Rust
- Scala
- Standard ML
- Tcl
- UNIX Shell
- Wren
- Zkl
- Clojure/Omit
- GUISS/Omit
- Java/Omit
- Processing/Omit
- TI-83 BASIC/Omit
- ZX Spectrum Basic/Omit