How to simulate a shell without tty?

Solution 1:

The tty isn't provided by a shell (the relationship is the opposite). The tty is provided by a terminal emulator. Programs can "detach" themselves from the terminal in two parts (it depends on what the tested program actually checks for)

  1. Close stdin/stdout/stderr (which normally point to the terminal); for example, you could redirect input from /dev/null, and send output to a file or through a pipe:

    true | myapp 2>&1 | cat
    
    myapp </dev/null |& cat
    
  2. Call setsid() to detach from the controlling terminal (which otherwise would remain accessible through /dev/tty and would make the program subject to the shell's job control). From a shell you could use the tool of the same name:

    setsid myapp
    

So combining these two, I think you could run your test script like this:

true | (setsid ./testscript.sh) 2>&1 | cat

(setsid ./testscript.sh) </dev/null |& cat

(Yes, the parentheses are intentional – they prevent the setsid tool from having to fork and unexpectedly go "into background".)