Search code examples
ioocaml

Is it possible to know if a text input is from a pipe only


I want to make a program that prompts the user to enter something with an introduction text. Something like "Please write something". But if there is a text from a pipe, the result is displayed directly without any introduction test.

I started a program that read input and answer to the user in Ocaml. But how to make it detecting the absence of pipe ?

If something is piped to that program the introduction text doesn't make sense.

open In_channel

let answer inp =
    match inp with
    None -> "this is None" |
    Some "" -> "this is empty" |
    Some x -> "you wrote " ^ x

let () =
  print_endline "Please write something" ; 
  print_endline (answer (input_line stdin) ^ "\nend")

It's not a big deal if the solution is Unix only. Thank you in advance.


Solution

  • A very straightforward modification to your code based on using Unix.isatty to determine whether or not to print the prompt.

    open In_channel
    
    let answer = function
        None -> "this is None" 
      | Some "" -> "this is empty" 
      | Some x -> "you wrote " ^ x
    
    let () =
      if Unix.isatty stdin then
        print_endline "Please write something"; 
      print_endline (answer (input_line stdin));
      print_endline "end"
    

    As of OCaml 5.1 (released Sept 2023) In_channel.isatty exists, and you've already opened In_channel, so you could reduce the above to:

    open In_channel
    
    let answer = function
        None -> "this is None" 
      | Some "" -> "this is empty" 
      | Some x -> "you wrote " ^ x
    
    let () =
      if isatty stdin then
        print_endline "Please write something"; 
      print_endline (answer (input_line stdin));
      print_endline "end"