How to check STDIN come from a pipe?

Following is a working example from ruby:

#!/usr/bin/env ruby
# -*- coding: utf-8; mode: ruby; -*-

if $stdin.stat.pipe?
  puts $stdin.read
else
  puts "not pipe"
end
$: ./test                     # => not pipe
$: echo hello |./test         # => hello

I can use BASH shell like this:

p `test -p /proc/$$/fd/0; echo $?`.chomp # 0 if read from pipe, otherwize 1.

But i don’t know if this hack works on MacOS.

What i want it write following code Crystal way.

is_pipe = `test -p /proc/$$/fd/0; echo $?`.chomp == "0"

if is_pipe
  puts STDIN.gets
else
  ARGV << "--help" if ARGV.empty?
  puts ARGV
end

Thank you.

if STDIN.info.type.pipe?
  puts STDIN.gets
else
  puts "not a pipe"
end

IO::FileDescriptor#info is undocumented, but it is more or less equivalent to File.info(STDIN) as long as STDIN is open. Both return a File::Info whose #type tells whether there is a pipe.

4 Likes

STDIN.tty? works.

# foo.cr
pp! STDIN.tty?
$ ./foo
STDIN.tty? # => true
$ cat foo.cr | ./foo
STDIN.tty? # => false
2 Likes