Check output device is a terminal: Difference between revisions
m (→{{header|Phix}}: added syntax colouring, marked p2js incompatible) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 14: | Line 14: | ||
=={{header|6502 Assembly}}== |
=={{header|6502 Assembly}}== |
||
{{works with|Commodore 64}} |
{{works with|Commodore 64}} |
||
< |
<syntaxhighlight lang=6502asm>LDA $D011 ;screen control register 1 |
||
AND #%00100000 ;bit 5 clear = text mode, bit 5 set = gfx mode |
AND #%00100000 ;bit 5 clear = text mode, bit 5 set = gfx mode |
||
BEQ isTerminal</ |
BEQ isTerminal</syntaxhighlight> |
||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
Line 22: | Line 22: | ||
We use the interface to C library functions <code>isatty()</code> and <code>fileno()</code>. |
We use the interface to C library functions <code>isatty()</code> and <code>fileno()</code>. |
||
< |
<syntaxhighlight lang=ada>with Ada.Text_IO; use Ada.Text_IO; |
||
with Interfaces.C_Streams; use Interfaces.C_Streams; |
with Interfaces.C_Streams; use Interfaces.C_Streams; |
||
Line 32: | Line 32: | ||
Put_Line(Standard_Error, "stdout is a tty."); |
Put_Line(Standard_Error, "stdout is a tty."); |
||
end if; |
end if; |
||
end Test_tty;</ |
end Test_tty;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 47: | Line 47: | ||
Use <code>isatty()</code> on file descriptor to determine if it's a TTY. To get the file descriptor from a <code>FILE*</code> pointer, use <code>fileno</code>: |
Use <code>isatty()</code> on file descriptor to determine if it's a TTY. To get the file descriptor from a <code>FILE*</code> pointer, use <code>fileno</code>: |
||
< |
<syntaxhighlight lang=c>#include <unistd.h> // for isatty() |
||
#include <stdio.h> // for fileno() |
#include <stdio.h> // for fileno() |
||
Line 56: | Line 56: | ||
: "stdout is not tty"); |
: "stdout is not tty"); |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 73: | Line 73: | ||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
< |
<syntaxhighlight lang=csharp>using System; |
||
namespace CheckTerminal { |
namespace CheckTerminal { |
||
Line 81: | Line 81: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C++}}== |
=={{header|C++}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang=cpp>#if _WIN32 |
||
#include <io.h> |
#include <io.h> |
||
#define ISATTY _isatty |
#define ISATTY _isatty |
||
Line 105: | Line 105: | ||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|COBOL}}== |
=={{header|COBOL}}== |
||
Works with GnuCOBOL. |
Works with GnuCOBOL. |
||
< |
<syntaxhighlight lang=cobol> *> |
||
*> istty, check id fd 0 is a tty |
*> istty, check id fd 0 is a tty |
||
*> Tectonics: cobc -xj istty.cob |
*> Tectonics: cobc -xj istty.cob |
||
Line 135: | Line 135: | ||
goback. |
goback. |
||
end program istty.</ |
end program istty.</syntaxhighlight> |
||
DISPLAY for fd 1 is directed to SYSERR to get some output during the various trials. |
DISPLAY for fd 1 is directed to SYSERR to get some output during the various trials. |
||
Line 160: | Line 160: | ||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
{{Works with|SBCL}} |
{{Works with|SBCL}} |
||
< |
<syntaxhighlight lang=lisp>(with-open-stream (s *standard-output*) |
||
(format T "stdout is~:[ not~;~] a terminal~%" |
(format T "stdout is~:[ not~;~] a terminal~%" |
||
(interactive-stream-p s)))</ |
(interactive-stream-p s)))</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
Line 176: | Line 176: | ||
We use the interface to C library functions <code>isatty()</code> and <code>fileno()</code>. It needs to be compiled to be executed. |
We use the interface to C library functions <code>isatty()</code> and <code>fileno()</code>. It needs to be compiled to be executed. |
||
< |
<syntaxhighlight lang=lisp>(ffi:clines " |
||
#include <sys/ioctl.h> |
#include <sys/ioctl.h> |
||
#include <unistd.h> |
#include <unistd.h> |
||
Line 193: | Line 193: | ||
(format T "stdout is~:[ not~;~] a terminal~%" (tty-p)) |
(format T "stdout is~:[ not~;~] a terminal~%" (tty-p)) |
||
(quit)</ |
(quit)</syntaxhighlight> |
||
Compilation can be done with the following commands : |
Compilation can be done with the following commands : |
||
Line 208: | Line 208: | ||
=={{header|Crystal}}== |
=={{header|Crystal}}== |
||
< |
<syntaxhighlight lang=ruby>File.new("testfile").tty? #=> false |
||
File.new("/dev/tty").tty? #=> true |
File.new("/dev/tty").tty? #=> true |
||
STDOUT.tty? #=> true</ |
STDOUT.tty? #=> true</syntaxhighlight> |
||
=={{header|D}}== |
=={{header|D}}== |
||
< |
<syntaxhighlight lang=D>import std.stdio; |
||
extern(C) int isatty(int); |
extern(C) int isatty(int); |
||
Line 219: | Line 219: | ||
void main() { |
void main() { |
||
writeln("Stdout is tty: ", stdout.fileno.isatty == 1); |
writeln("Stdout is tty: ", stdout.fileno.isatty == 1); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 231: | Line 231: | ||
=={{header|Factor}}== |
=={{header|Factor}}== |
||
You have to know 1 is the correct file descriptor number: |
You have to know 1 is the correct file descriptor number: |
||
< |
<syntaxhighlight lang=factor> |
||
IN: scratchpad USE: unix.ffi |
IN: scratchpad USE: unix.ffi |
||
IN: scratchpad 1 isatty |
IN: scratchpad 1 isatty |
||
Line 237: | Line 237: | ||
--- Data stack: |
--- Data stack: |
||
1 |
1 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|FreeBASIC}}== |
=={{header|FreeBASIC}}== |
||
< |
<syntaxhighlight lang=freebasic> |
||
Open Cons For Output As #1 |
Open Cons For Output As #1 |
||
' Open Cons abre los flujos de entrada (stdin) o salida (stdout) estándar |
' Open Cons abre los flujos de entrada (stdin) o salida (stdout) estándar |
||
Line 253: | Line 253: | ||
Close #1 |
Close #1 |
||
Sleep |
Sleep |
||
</syntaxhighlight> |
|||
</lang> |
|||
Line 259: | Line 259: | ||
Tells a ''terminal'' apart from a ''pipe'' on Linux and Mac, which is probably exactly what you need. |
Tells a ''terminal'' apart from a ''pipe'' on Linux and Mac, which is probably exactly what you need. |
||
< |
<syntaxhighlight lang=go>package main |
||
import ( |
import ( |
||
Line 272: | Line 272: | ||
fmt.Println("Who are you? You're not a terminal") |
fmt.Println("Who are you? You're not a terminal") |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 283: | Line 283: | ||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
< |
<syntaxhighlight lang=haskell>module Main where |
||
-- requires the unix package |
-- requires the unix package |
||
Line 296: | Line 296: | ||
(if istty |
(if istty |
||
then "stdout is tty" |
then "stdout is tty" |
||
else "stdout is not tty")</ |
else "stdout is not tty")</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre>$ runhaskell istty.hs |
<pre>$ runhaskell istty.hs |
||
Line 306: | Line 306: | ||
=={{header|J}}== |
=={{header|J}}== |
||
< |
<syntaxhighlight lang=J>3=nc<'wd'</syntaxhighlight> |
||
Explanation: |
Explanation: |
||
Line 321: | Line 321: | ||
=={{header|Javascript/NodeJS}}== |
=={{header|Javascript/NodeJS}}== |
||
< |
<syntaxhighlight lang=js>node -p -e "Boolean(process.stdout.isTTY)" |
||
true</ |
true</syntaxhighlight> |
||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
< |
<syntaxhighlight lang=Julia> |
||
if isa(STDOUT, Base.TTY) |
if isa(STDOUT, Base.TTY) |
||
println("This program sees STDOUT as a TTY.") |
println("This program sees STDOUT as a TTY.") |
||
Line 331: | Line 331: | ||
println("This program does not see STDOUT as a TTY.") |
println("This program does not see STDOUT as a TTY.") |
||
end |
end |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 340: | Line 340: | ||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
{{Works with|Ubuntu|14.04}} |
{{Works with|Ubuntu|14.04}} |
||
< |
<syntaxhighlight lang=scala>// Kotlin Native version 0.5 |
||
import platform.posix.* |
import platform.posix.* |
||
Line 349: | Line 349: | ||
else |
else |
||
println("stdout is not a terminal") |
println("stdout is not a terminal") |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 359: | Line 359: | ||
{{works with|Lua|5.1+}} |
{{works with|Lua|5.1+}} |
||
Using pure Lua, assuming a *NIX-like runtime environment ... |
Using pure Lua, assuming a *NIX-like runtime environment ... |
||
< |
<syntaxhighlight lang=Lua>local function isTTY ( fd ) |
||
fd = tonumber( fd ) or 1 |
fd = tonumber( fd ) or 1 |
||
local ok, exit, signal = os.execute( string.format( "test -t %d", fd ) ) |
local ok, exit, signal = os.execute( string.format( "test -t %d", fd ) ) |
||
Line 367: | Line 367: | ||
print( "stdin", isTTY( 0 ) ) |
print( "stdin", isTTY( 0 ) ) |
||
print( "stdout", isTTY( 1 ) ) |
print( "stdout", isTTY( 1 ) ) |
||
print( "stderr", isTTY( 2 ) )</ |
print( "stderr", isTTY( 2 ) )</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 393: | Line 393: | ||
You can accomplish the same results using the luaposix [https://github.com/luaposix/luaposix] library: |
You can accomplish the same results using the luaposix [https://github.com/luaposix/luaposix] library: |
||
< |
<syntaxhighlight lang=lua>local unistd = require( "posix.unistd" ) |
||
local function isTTY ( fd ) |
local function isTTY ( fd ) |
||
Line 403: | Line 403: | ||
print( "stdin", isTTY( 0 ) ) |
print( "stdin", isTTY( 0 ) ) |
||
print( "stdout", isTTY( 1 ) ) |
print( "stdout", isTTY( 1 ) ) |
||
print( "stderr", isTTY( 2 ) )</ |
print( "stderr", isTTY( 2 ) )</syntaxhighlight> |
||
The output of this version is identical to the output of the first version. |
The output of this version is identical to the output of the first version. |
||
Line 409: | Line 409: | ||
=={{header|Nemerle}}== |
=={{header|Nemerle}}== |
||
There is no explicit way (ie <tt>isatty()</tt>)to do this; however, if we ''assume'' that standard out ''is'' a terminal, we can check if the output stream has been redirected (presumably to something other than a terminal). |
There is no explicit way (ie <tt>isatty()</tt>)to do this; however, if we ''assume'' that standard out ''is'' a terminal, we can check if the output stream has been redirected (presumably to something other than a terminal). |
||
< |
<syntaxhighlight lang=Nemerle>def isTerm = System.Console.IsOutputRedirected;</syntaxhighlight> |
||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
Line 415: | Line 415: | ||
As we want to redirect stdout, we write the messages on stderr. |
As we want to redirect stdout, we write the messages on stderr. |
||
< |
<syntaxhighlight lang=Nim>import terminal |
||
stderr.write if stdout.isatty: "stdout is a terminal\n" else: "stdout is not a terminal\n"</ |
stderr.write if stdout.isatty: "stdout is a terminal\n" else: "stdout is not a terminal\n"</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 428: | Line 428: | ||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
< |
<syntaxhighlight lang=ocaml>let () = |
||
print_endline ( |
print_endline ( |
||
if Unix.isatty Unix.stdout |
if Unix.isatty Unix.stdout |
||
then "Output goes to tty." |
then "Output goes to tty." |
||
else "Output doesn't go to tty." |
else "Output doesn't go to tty." |
||
)</ |
)</syntaxhighlight> |
||
Testing in interpreted mode: |
Testing in interpreted mode: |
||
Line 449: | Line 449: | ||
=={{header|Ol}}== |
=={{header|Ol}}== |
||
< |
<syntaxhighlight lang=scheme> |
||
(define (isatty? fd) (syscall 16 fd 19)) |
(define (isatty? fd) (syscall 16 fd 19)) |
||
(print (if (isatty? stdout) |
(print (if (isatty? stdout) |
||
"stdout is a tty." |
"stdout is a tty." |
||
"stdout is not a tty.")) |
"stdout is not a tty.")) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
The -t function on a filehandle tells you whether it's a terminal. |
The -t function on a filehandle tells you whether it's a terminal. |
||
< |
<syntaxhighlight lang=bash>$ perl -e "warn -t STDOUT ? 'Terminal' : 'Other'" |
||
Terminal |
Terminal |
||
$ perl -e "warn -t STDOUT ? 'Terminal' : 'Other'" > x.tmp |
$ perl -e "warn -t STDOUT ? 'Terminal' : 'Other'" > x.tmp |
||
Other |
Other |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
<!--< |
<!--<syntaxhighlight lang=Phix>(notonline)--> |
||
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- (no input or output redirection in a browser!)</span> |
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- (no input or output redirection in a browser!)</span> |
||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"stdin:%t, stdout:%t, stderr:%t\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">isatty</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">),</span><span style="color: #000000;">isatty</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">),</span><span style="color: #000000;">isatty</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)})</span> |
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"stdin:%t, stdout:%t, stderr:%t\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">isatty</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">),</span><span style="color: #000000;">isatty</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">),</span><span style="color: #000000;">isatty</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)})</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 486: | Line 486: | ||
=={{header|PHP}}== |
=={{header|PHP}}== |
||
< |
<syntaxhighlight lang=php> |
||
if(posix_isatty(STDOUT)) { |
if(posix_isatty(STDOUT)) { |
||
echo "The output device is a terminal".PHP_EOL; |
echo "The output device is a terminal".PHP_EOL; |
||
Line 492: | Line 492: | ||
echo "The output device is NOT a terminal".PHP_EOL; |
echo "The output device is NOT a terminal".PHP_EOL; |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Python}}== |
=={{header|Python}}== |
||
Pretty much the same as [[Check input device is a terminal#Python]]. |
Pretty much the same as [[Check input device is a terminal#Python]]. |
||
< |
<syntaxhighlight lang=python>from sys import stdout |
||
if stdout.isatty(): |
if stdout.isatty(): |
||
print 'The output device is a teletype. Or something like a teletype.' |
print 'The output device is a teletype. Or something like a teletype.' |
||
else: |
else: |
||
print 'The output device isn\'t like a teletype.'</ |
print 'The output device isn\'t like a teletype.'</syntaxhighlight> |
||
=={{header|Quackery}}== |
=={{header|Quackery}}== |
||
Line 506: | Line 506: | ||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang=Quackery> [ $ |from sys import stdout |
||
to_stack( 1 if stdout.isatty() else 0)| |
to_stack( 1 if stdout.isatty() else 0)| |
||
python ] is ttyout ( --> b ) |
python ] is ttyout ( --> b ) |
||
Line 513: | Line 513: | ||
[ say "Looks like a teletype." ] |
[ say "Looks like a teletype." ] |
||
else |
else |
||
[ say "Not a teletype." ]</ |
[ say "Not a teletype." ]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 520: | Line 520: | ||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
< |
<syntaxhighlight lang=racket> |
||
(terminal-port? (current-output-port)) |
(terminal-port? (current-output-port)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Raku}}== |
=={{header|Raku}}== |
||
Line 555: | Line 555: | ||
<br>On IBM mainframes, a user can have STDIN defined, but the terminal can be ''disconnected''. |
<br>On IBM mainframes, a user can have STDIN defined, but the terminal can be ''disconnected''. |
||
< |
<syntaxhighlight lang=rexx>/*REXX program determines if the STDIN is a terminal device or other. */ |
||
signal on syntax /*if syntax error, then jump ──► SYNTAX*/ |
signal on syntax /*if syntax error, then jump ──► SYNTAX*/ |
||
say 'output device:' testSTDIN() /*displays terminal ──or── other */ |
say 'output device:' testSTDIN() /*displays terminal ──or── other */ |
||
Line 568: | Line 568: | ||
end /* [↑] can't use a RETURN here. */ |
end /* [↑] can't use a RETURN here. */ |
||
/* ··· handle other REXX syntax errors here ··· */</ |
/* ··· handle other REXX syntax errors here ··· */</syntaxhighlight> |
||
{{out|output|text= when using the default input:}} |
{{out|output|text= when using the default input:}} |
||
<pre> |
<pre> |
||
Line 591: | Line 591: | ||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
< |
<syntaxhighlight lang=rust>f = File.open("test.txt") |
||
p f.isatty # => false |
p f.isatty # => false |
||
p STDOUT.isatty # => true |
p STDOUT.isatty # => true |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
< |
<syntaxhighlight lang=rust>/* Uses C library interface */ |
||
extern crate libc; |
extern crate libc; |
||
Line 608: | Line 608: | ||
println!("stdout is not tty"); |
println!("stdout is not tty"); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
{{Works with|Ubuntu|14.04}} |
{{Works with|Ubuntu|14.04}} |
||
< |
<syntaxhighlight lang=scala>import org.fusesource.jansi.internal.CLibrary._ |
||
object IsATty extends App { |
object IsATty extends App { |
||
Line 632: | Line 632: | ||
println("tty " + apply(true)) |
println("tty " + apply(true)) |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Standard ML}}== |
=={{header|Standard ML}}== |
||
< |
<syntaxhighlight lang=sml>val stdoutRefersToTerminal : bool = Posix.ProcEnv.isatty Posix.FileSys.stdout</syntaxhighlight> |
||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
To detect whether output is going to a terminal in Tcl, you check whether the <code>stdout</code> channel looks like a serial line (as those are indistinguishable from terminals). The simplest way of doing that is to see whether you can read the <tt>-mode</tt> or <code>-xchar</code> channel options, which are only present on serial channels: |
To detect whether output is going to a terminal in Tcl, you check whether the <code>stdout</code> channel looks like a serial line (as those are indistinguishable from terminals). The simplest way of doing that is to see whether you can read the <tt>-mode</tt> or <code>-xchar</code> channel options, which are only present on serial channels: |
||
< |
<syntaxhighlight lang=tcl>set toTTY [dict exists [fconfigure stdout] -mode] |
||
puts [expr {$toTTY ? "Output goes to tty" : "Output doesn't go to tty"}]</ |
puts [expr {$toTTY ? "Output goes to tty" : "Output doesn't go to tty"}]</syntaxhighlight> |
||
At the system call level, when Tcl is setting up the channels that correspond to the underlying <tt>stdout</tt> (and <tt>stdin</tt> and <tt>stderr</tt>) file descriptors, it checks whether the channels are network sockets (with <code>getsockname()</code>) or serial lines (with <code>isatty()</code>). This allows Tcl scripts to find out information about their calling environment (e.g., when they are run from <tt>inetd</tt>) with minimal code. |
At the system call level, when Tcl is setting up the channels that correspond to the underlying <tt>stdout</tt> (and <tt>stdin</tt> and <tt>stderr</tt>) file descriptors, it checks whether the channels are network sockets (with <code>getsockname()</code>) or serial lines (with <code>isatty()</code>). This allows Tcl scripts to find out information about their calling environment (e.g., when they are run from <tt>inetd</tt>) with minimal code. |
||
{{out|Demonstrating}} |
{{out|Demonstrating}} |
||
Line 650: | Line 650: | ||
===Channel type discovery with older Tcl versions=== |
===Channel type discovery with older Tcl versions=== |
||
Before Tcl 8.4, this discovery process is impossible; <code>stdout</code> always looks like it is going to a file. With 8.4, you can discover the channel type but you need slightly different (and less efficient, due to the thrown error in the non-tty case) code to do it. |
Before Tcl 8.4, this discovery process is impossible; <code>stdout</code> always looks like it is going to a file. With 8.4, you can discover the channel type but you need slightly different (and less efficient, due to the thrown error in the non-tty case) code to do it. |
||
< |
<syntaxhighlight lang=tcl>set toTTY [expr {![catch {fconfigure stdout -mode}]}]</syntaxhighlight> |
||
=={{header|UNIX Shell}}== |
=={{header|UNIX Shell}}== |
||
< |
<syntaxhighlight lang=sh>#!/bin/sh |
||
if [ -t 1 ] |
if [ -t 1 ] |
||
Line 660: | Line 660: | ||
else |
else |
||
echo "Output is NOT a terminal" >/dev/tty |
echo "Output is NOT a terminal" >/dev/tty |
||
fi</ |
fi</syntaxhighlight> |
||
=={{header|Visual Basic .NET}}== |
=={{header|Visual Basic .NET}}== |
||
{{trans|C#}} |
{{trans|C#}} |
||
< |
<syntaxhighlight lang=vbnet>Module Module1 |
||
Sub Main() |
Sub Main() |
||
Line 670: | Line 670: | ||
End Sub |
End Sub |
||
End Module</ |
End Module</syntaxhighlight> |
||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
{{trans|C}} |
{{trans|C}} |
||
As there is currently no way to obtain this information via Wren CLI, we instead embed a Wren script in a C application and ask the host program to get it for us. |
As there is currently no way to obtain this information via Wren CLI, we instead embed a Wren script in a C application and ask the host program to get it for us. |
||
< |
<syntaxhighlight lang=ecmascript>/* check_output_device_is_terminal.wren */ |
||
class C { |
class C { |
||
Line 681: | Line 681: | ||
} |
} |
||
System.print("Output device is a terminal = %(C.isOutputDeviceTerminal)")</ |
System.print("Output device is a terminal = %(C.isOutputDeviceTerminal)")</syntaxhighlight> |
||
<br> |
<br> |
||
We now embed this Wren script in the following C program, compile and run it. |
We now embed this Wren script in the following C program, compile and run it. |
||
< |
<syntaxhighlight lang=c>#include <stdlib.h> |
||
#include <unistd.h> |
#include <unistd.h> |
||
#include <stdio.h> |
#include <stdio.h> |
||
Line 765: | Line 765: | ||
free(script); |
free(script); |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 782: | Line 782: | ||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
On Unix, check to see if stdout's st_mode is a character device. |
On Unix, check to see if stdout's st_mode is a character device. |
||
< |
<syntaxhighlight lang=zkl>const S_IFCHR=0x2000; |
||
fcn S_ISCHR(f){ f.info()[4].bitAnd(S_IFCHR).toBool() } |
fcn S_ISCHR(f){ f.info()[4].bitAnd(S_IFCHR).toBool() } |
||
S_ISCHR(File.stdout).println();</ |
S_ISCHR(File.stdout).println();</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
Revision as of 19:26, 26 August 2022
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 output device is a terminal or not.
- Related task
6502 Assembly
LDA $D011 ;screen control register 1
AND #%00100000 ;bit 5 clear = text mode, bit 5 set = gfx mode
BEQ isTerminal
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(Stdout)) = 0 then
Put_Line(Standard_Error, "stdout is not a tty.");
else
Put_Line(Standard_Error, "stdout is a tty.");
end if;
end Test_tty;
- Output:
$ ./test_tty stdout is a tty. $ ./test_tty > /dev/null stdout 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()
{
puts(isatty(fileno(stdout))
? "stdout is tty"
: "stdout is not tty");
return 0;
}
- Output:
$ ./a.out stdout is tty $ ./a.out > tmp $ cat tmp stdout is not tty $ ./a.out | cat stdout is not tty
C#
using System;
namespace CheckTerminal {
class Program {
static void Main(string[] args) {
Console.WriteLine("Stdout is tty: {0}", Console.IsOutputRedirected);
}
}
}
C++
#if _WIN32
#include <io.h>
#define ISATTY _isatty
#define FILENO _fileno
#else
#include <unistd.h>
#define ISATTY isatty
#define FILENO fileno
#endif
#include <iostream>
int main() {
if (ISATTY(FILENO(stdout))) {
std::cout << "stdout is a tty\n";
} else {
std::cout << "stdout is not a tty\n";
}
return 0;
}
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-output*)
(format T "stdout is~:[ not~;~] a terminal~%"
(interactive-stream-p s)))
- Output:
$ sbcl --script rc.lisp stdout is a terminal $ sbcl --script rc.lisp | cat stdout is not a terminal $ sbcl --script rc.lisp > foo.txt $ cat foo.txt stdout is not a terminal
We use the interface to C library functions isatty()
and fileno()
. It needs to be compiled to be executed.
(ffi:clines "
#include <sys/ioctl.h>
#include <unistd.h>
int ttyPredicate() {
return isatty(fileno(stdout));
}")
(ffi:def-function
("ttyPredicate" c-ttyp)
() :returning :int)
(defun tty-p()
(if (= 1 (c-ttyp))
t
nil))
(format T "stdout is~:[ not~;~] a terminal~%" (tty-p))
(quit)
Compilation can be done with the following commands :
ecl --eval '(compile-file "file.lisp" :system-p t)' --eval '(quit)'
ecl --eval '(c:build-program "is-tty" :lisp-files (list "file.o"))' --eval '(quit)'
- Output:
$ ./is-tty stdout is a terminal $ ./is-tty | cat - stdout is not a terminal
Crystal
File.new("testfile").tty? #=> false
File.new("/dev/tty").tty? #=> true
STDOUT.tty? #=> true
D
import std.stdio;
extern(C) int isatty(int);
void main() {
writeln("Stdout is tty: ", stdout.fileno.isatty == 1);
}
- Output:
prompt>a.out Stdout is tty: true prompt>a.out > out.txt Stdout is tty: false
Factor
You have to know 1 is the correct file descriptor number:
IN: scratchpad USE: unix.ffi
IN: scratchpad 1 isatty
--- Data stack:
1
FreeBASIC
Open Cons For Output As #1
' Open Cons abre los flujos de entrada (stdin) o salida (stdout) estándar
' de la consola para leer o escribir.
If Err > 0 Then
Print #1, "stdout is not a tty."
Else
Print #1, "stdout is a tty."
End If
Close #1
Sleep
Go
Tells a terminal apart from a pipe on Linux and Mac, which is probably exactly what you need.
package main
import (
"os"
"fmt"
)
func main() {
if fileInfo, _ := os.Stdout.Stat(); (fileInfo.Mode() & os.ModeCharDevice) != 0 {
fmt.Println("Hello terminal")
} else {
fmt.Println("Who are you? You're not a terminal")
}
}
- Output:
> hello Hello terminal > hello | cat Who are you? You're not a terminal.
Haskell
module Main where
-- requires the unix package
-- https://hackage.haskell.org/package/unix
import System.Posix.Terminal (queryTerminal)
import System.Posix.IO (stdOutput)
main :: IO ()
main = do
istty <- queryTerminal stdOutput
putStrLn
(if istty
then "stdout is tty"
else "stdout is not tty")
- Output:
$ runhaskell istty.hs stdout is tty $ runhaskell istty.hs | cat stdout is not tty
J
3=nc<'wd'
Explanation:
J does not have a concept of an "output device", so we approximate that by seeing whether we have bothered to define a the code which typically does graphical output.
The use of the phrase "output device" suggests that we are thinking about something like the unix `isatty` command. Here, stdout might be a file or might be a terminal. But in J we are often hosting our own user interaction environment. It's not uncommon for a J user to be on a web page where hitting enter sends a form request to a J interpreter which in turn composes an updated html presentation of current state which it sends to the browser. Or, the J user might be talking to a Java program which similarly wraps the J session (though this is older technology at this point). Or, the J user might be interacting with Qt. Or, sure, we might be talking to a tty and J might be sending its output straight to the tty. (But we can't know if that tty is hosted in emacs, running under control of a script on a remote machine via ssh, talking directly to a human user who happens to be in direct control of the session, or whatever else...)
The point being that in the general case the J programmer cannot know whether the concept of "terminal" has any relevance to the user.
But, like everyone else, we can certainly use heuristics.
But, correctness requires us to keep in mind that these will only be heuristics, and will sometimes be incorrect (hopefully not often enough to matter a lot...).
Javascript/NodeJS
node -p -e "Boolean(process.stdout.isTTY)"
true
Julia
if isa(STDOUT, Base.TTY)
println("This program sees STDOUT as a TTY.")
else
println("This program does not see STDOUT as a TTY.")
end
- Output:
This program sees STDOUT as a TTY.
Kotlin
// Kotlin Native version 0.5
import platform.posix.*
fun main(args: Array<String>) {
if (isatty(STDOUT_FILENO) != 0)
println("stdout is a terminal")
else
println("stdout is not a terminal")
}
- Output:
stdout is a terminal
Lua
Using pure Lua, assuming a *NIX-like runtime environment ...
local function isTTY ( fd )
fd = tonumber( fd ) or 1
local ok, exit, signal = os.execute( string.format( "test -t %d", fd ) )
return (ok and exit == "exit") and signal == 0 or false
end
print( "stdin", isTTY( 0 ) )
print( "stdout", isTTY( 1 ) )
print( "stderr", isTTY( 2 ) )
- Output:
$ lua istty.lua stdin true stdout true stderr true $ cat /dev/null | lua istty.lua stdin false stdout true stderr true $ lua istty.lua | tee stdin true stdout false stderr true $ lua istty.lua 2>&1 | tee stdin true stdout false stderr false
You can accomplish the same results using the luaposix [1] library:
local unistd = require( "posix.unistd" )
local function isTTY ( fd )
fd = tonumber( fd ) or 1
local ok, err, errno = unistd.isatty( fd )
return ok and true or false
end
print( "stdin", isTTY( 0 ) )
print( "stdout", isTTY( 1 ) )
print( "stderr", isTTY( 2 ) )
The output of this version is identical to the output of the first version.
Nemerle
There is no explicit way (ie isatty())to do this; however, if we assume that standard out is a terminal, we can check if the output stream has been redirected (presumably to something other than a terminal).
def isTerm = System.Console.IsOutputRedirected;
Nim
Using function "isatty" of standard module "terminal" which accepts a File as argument. As we want to redirect stdout, we write the messages on stderr.
import terminal
stderr.write if stdout.isatty: "stdout is a terminal\n" else: "stdout is not a terminal\n"
- Output:
Command: ./check_output_dev Result: stdout is a terminal
Command: ./check_output_dev >somefile Result: stdout is not a terminal
OCaml
let () =
print_endline (
if Unix.isatty Unix.stdout
then "Output goes to tty."
else "Output doesn't go to tty."
)
Testing in interpreted mode:
$ ocaml unix.cma istty.ml Output goes to tty. $ ocaml unix.cma istty.ml > tmp $ cat tmp Output doesn't go to tty. $ ocaml unix.cma istty.ml | cat Output doesn't go to tty.
Ol
(define (isatty? fd) (syscall 16 fd 19))
(print (if (isatty? stdout)
"stdout is a tty."
"stdout is not a tty."))
Perl
The -t function on a filehandle tells you whether it's a terminal.
$ perl -e "warn -t STDOUT ? 'Terminal' : 'Other'"
Terminal
$ perl -e "warn -t STDOUT ? 'Terminal' : 'Other'" > x.tmp
Other
Phix
without js -- (no input or output 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>p test > test.txt; type test.txt stdin:true, stdout:false, stderr:true C:\Program Files (x86)\Phix>p test 2> test.txt stdin:true, stdout:true, stderr:false C:\Program Files (x86)\Phix>type test.txt | p test stdin:false, stdout:true, stderr:true
PHP
if(posix_isatty(STDOUT)) {
echo "The output device is a terminal".PHP_EOL;
} else {
echo "The output device is NOT a terminal".PHP_EOL;
}
Python
Pretty much the same as Check input device is a terminal#Python.
from sys import stdout
if stdout.isatty():
print 'The output device is a teletype. Or something like a teletype.'
else:
print 'The output device isn\'t like a teletype.'
Quackery
[ $ |from sys import stdout
to_stack( 1 if stdout.isatty() else 0)|
python ] is ttyout ( --> b )
ttyout if
[ say "Looks like a teletype." ]
else
[ say "Not a teletype." ]
- Output:
Looks like a teletype.
Racket
(terminal-port? (current-output-port))
Raku
(formerly Perl 6)
The .t method on a filehandle tells you whether it's going to the terminal. Here we use the note function to emit our result to standard error rather than standard out.
$ raku -e 'note $*OUT.t' True $ raku -e 'note $*OUT.t' >/dev/null False
REXX
Programming note: The comment about the REXX statements have to be on one line isn't quite true,
but because the REXX special variable SIGL is defined where it's executed, it makes coding simpler.
SIGL is set to the REXX statement number where:
- a CALL statement is used
- a function is invoked
- a SIGNAL statement is used
Method used: since REXX has no direct way of determining if the STDIN is a terminal or not, the REXX code (below)
actually raises (which is no way to run a railroad) a syntax error when attempting to read the 2nd line from STDIN,
which causes a routine (named syntax:) to get control, determines where the syntax error occurred, and returns
an appropriate string indicating if STDIN is a terminal (or other).
Note that under VM/CMS, this can be accomplished with a (host) command within REXX and then examining the results.
On IBM mainframes, a user can have STDIN defined, but the terminal can be disconnected.
/*REXX program determines if the STDIN is a terminal device or other. */
signal on syntax /*if syntax error, then jump ──► SYNTAX*/
say 'output device:' testSTDIN() /*displays terminal ──or── other */
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
testSTDIN: syntax.=1; signal .; .: z.= sigl; call linein ,2; ..: syntax.= 0; return z..
/* [↑] must/should be all on one line.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
syntax: z..= 'other' /*when a SYNTAX error occurs, come here*/
if syntax. then do /*are we handling STDIN thingy error?*/
if sigl==z. then z..= 'terminal'; signal .. /*is this a stdin ?*/
end /* [↑] can't use a RETURN here. */
/* ··· handle other REXX syntax errors here ··· */
- output when using the default input:
output device: terminal
The following is the output when used with R4 REXX:
- output when using the default input:
Reading console input (Press Ctrl-Z to quit): ◄■■■■■■■■ user input (pressed ENTER) ◄■■■■■■■■ user input (pressed ENTER a 2nd time) output device: 6
Ruby
f = File.open("test.txt")
p f.isatty # => false
p STDOUT.isatty # => true
Rust
/* Uses C library interface */
extern crate libc;
fn main() {
let istty = unsafe { libc::isatty(libc::STDOUT_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(STDOUT_FILENO) == 1
}
catch {
case ignore: Throwable =>
ignore.printStackTrace()
false
}
}
println("tty " + apply(true))
}
Standard ML
val stdoutRefersToTerminal : bool = Posix.ProcEnv.isatty Posix.FileSys.stdout
Tcl
To detect whether output is going to a terminal in Tcl, you check whether the stdout
channel looks like a serial line (as those are indistinguishable from terminals). The simplest way of doing that is to see whether you can read the -mode or -xchar
channel options, which are only present on serial channels:
set toTTY [dict exists [fconfigure stdout] -mode]
puts [expr {$toTTY ? "Output goes to tty" : "Output doesn't go to tty"}]
At the system call level, when Tcl is setting up the channels that correspond to the underlying stdout (and stdin and stderr) file descriptors, it checks whether the channels are network sockets (with getsockname()
) or serial lines (with isatty()
). This allows Tcl scripts to find out information about their calling environment (e.g., when they are run from inetd) with minimal code.
- Demonstrating:
Assuming that the above script is stored in the file istty.tcl:
$ tclsh8.5 istty.tcl Output goes to tty $ tclsh8.5 istty.tcl | cat Output doesn't go to tty
Channel type discovery with older Tcl versions
Before Tcl 8.4, this discovery process is impossible; stdout
always looks like it is going to a file. With 8.4, you can discover the channel type but you need slightly different (and less efficient, due to the thrown error in the non-tty case) code to do it.
set toTTY [expr {![catch {fconfigure stdout -mode}]}]
UNIX Shell
#!/bin/sh
if [ -t 1 ]
then
echo "Output is a terminal"
else
echo "Output is NOT a terminal" >/dev/tty
fi
Visual Basic .NET
Module Module1
Sub Main()
Console.WriteLine("Stdout is tty: {0}", Console.IsOutputRedirected)
End Sub
End Module
Wren
As there is currently no way to obtain this information via Wren CLI, we instead embed a Wren script in a C application and ask the host program to get it for us.
/* check_output_device_is_terminal.wren */
class C {
foreign static isOutputDeviceTerminal
}
System.print("Output device is a terminal = %(C.isOutputDeviceTerminal)")
We now embed this Wren script in the following C program, compile and run it.
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include "wren.h"
void C_isOutputDeviceTerminal(WrenVM* vm) {
bool isTerminal = (bool)isatty(fileno(stdout));
wrenSetSlotBool(vm, 0, isTerminal);
}
WrenForeignMethodFn bindForeignMethod(
WrenVM* vm,
const char* module,
const char* className,
bool isStatic,
const char* signature) {
if (strcmp(module, "main") == 0) {
if (strcmp(className, "C") == 0) {
if (isStatic && strcmp(signature, "isOutputDeviceTerminal") == 0) {
return C_isOutputDeviceTerminal;
}
}
}
return NULL;
}
static void writeFn(WrenVM* vm, const char* text) {
printf("%s", text);
}
void errorFn(WrenVM* vm, WrenErrorType errorType, const char* module, const int line, const char* msg) {
switch (errorType) {
case WREN_ERROR_COMPILE:
printf("[%s line %d] [Error] %s\n", module, line, msg);
break;
case WREN_ERROR_STACK_TRACE:
printf("[%s line %d] in %s\n", module, line, msg);
break;
case WREN_ERROR_RUNTIME:
printf("[Runtime Error] %s\n", msg);
break;
}
}
char *readFile(const char *fileName) {
FILE *f = fopen(fileName, "r");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
rewind(f);
char *script = malloc(fsize + 1);
fread(script, 1, fsize, f);
fclose(f);
script[fsize] = 0;
return script;
}
int main() {
WrenConfiguration config;
wrenInitConfiguration(&config);
config.writeFn = &writeFn;
config.errorFn = &errorFn;
config.bindForeignMethodFn = &bindForeignMethod;
WrenVM* vm = wrenNewVM(&config);
const char* module = "main";
const char* fileName = "check_output_device_is_terminal.wren";
char *script = readFile(fileName);
WrenInterpretResult result = wrenInterpret(vm, module, script);
switch (result) {
case WREN_RESULT_COMPILE_ERROR:
printf("Compile Error!\n");
break;
case WREN_RESULT_RUNTIME_ERROR:
printf("Runtime Error!\n");
break;
case WREN_RESULT_SUCCESS:
break;
}
wrenFreeVM(vm);
free(script);
return 0;
}
- Output:
$ ./check_output_device_is_terminal Output device is a terminal = true $ ./check_output_device_is_terminal > tmp $ cat tmp Output device is a terminal = false $ ./check_output_device_is_terminal | cat Output device is a terminal = false
zkl
On Unix, check to see if stdout'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.stdout).println();
- Output:
$ zkl bbb # from the command line True $ zkl bbb | more False $ zkl bbb > foo.txt $ cat foo.txt False
- Programming Tasks
- Solutions by Programming Task
- Hardware
- Terminal control
- Initialization
- TI-83 BASIC/Omit
- 6502 Assembly
- Ada
- C
- C sharp
- C++
- COBOL
- Common Lisp
- Crystal
- D
- Factor
- FreeBASIC
- Go
- Haskell
- J
- Javascript/NodeJS
- Julia
- Kotlin
- Lua
- Posix
- Nemerle
- Nim
- OCaml
- Ol
- Perl
- Phix
- PHP
- Python
- Quackery
- Racket
- Raku
- REXX
- Ruby
- Rust
- Scala
- Standard ML
- Tcl
- UNIX Shell
- Visual Basic .NET
- Wren
- Zkl