How to simulate a shell without tty?
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)
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
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".)
Related videos on Youtube
Kalle Richter
Updated on September 18, 2022Comments
-
Kalle Richter over 1 year
I'm facing trouble with a system which I'm maintaining via SSH. When I test commands which require a TTY they work, probably because of the SSH session. Under some unclear circumstances there's no TTY available and commands like
sudo
fail due to(sudo: sorry, you must have a tty to run sudo)
They succeed in the SSH shell which makes issues hard to track before they occur. Since this is a recurring issue, I'm looking for a way to test changes to scripts in a shell which doesn't provide a TTY.
I'm using Ubuntu 19.04, CentOS 6 and Debian 9 with bash and ksh.
-
Jim L. about 5 yearsPossible duplicate of (superuser.com/questions/1375395/…)
-
-
Kalle Richter about 5 yearsThank you. Note: The check needs to be performed as non-root user.
-
renrutsirhc over 2 yearsEach non-rightmost component of a shell pipeline is already executed in its own subshell, the parentheses are redundant for that, and don't accomplish the goal of preventing setsid from forking in the case that setsid is the leftmost (or only) command in a pipeline in a shell with job control enabled.
-
Kamil Maciorowski about 2 yearsFor clarity: where you gave two pipelines one under the other, they are two independent variants and I can pick one that fits my needs better; I mean I don't need to run them both. Right?
-
user1686 about 2 years@Kamil: I think those were two separate examples, depending on the program's position in a pipeline.
-
Kamil Maciorowski about 2 yearsWhen I read it for the first time, I expected the code to continue, like it's a snippet from a script. It took me several seconds to realize it may not be the case. Consider a comment in between. Changing each empty line to
# or
should do.