9

Consider this sample C program which writes to /dev/tty and doesn't have command line options to make it not do so.

#include <stdio.h>

int main (void) {
    FILE* fout = fopen("/dev/tty", "w");
    fprintf(fout, "Hello, World!\n");
    fclose(fout);
}

How could I redirect the output of it to /dev/null in a shell script?

P.S. I read this answer, but I didn't understand much. In any case, I'm expecting an answer that doesn't modify the code source of the program.

2
  • why do you open /dev/tty when you mean to open /dev/null? – Marcus Müller May 3 at 12:16
  • 3
    @MarcusMüller It's just a sample program. The original program open /dev/tty and I would want to redirect it to /dev/null when running tests on it. I'll update the question. – Firmin Martin May 3 at 12:19
16

TL,DR:

script -c myprogram /dev/null </dev/null >/dev/null

You can't “redirect” /dev/tty in the same sense that you can redirect standard output. Standard output is defined as a file descriptor. Programs write to whatever file is already open on file descriptor 1 when they start. Some operating systems offer /dev/stdout as a file that's equivalent to standard output, but it's an “alias” for standard output. In contrast, /dev/tty is a file name, which refers to the process's controlling terminal. If a program opens /dev/tty, explicitly it opens /dev/tty, and that can't be redirected.

What you can do is run the program with a controlling terminal that isn't the same as the controlling terminal of the program that runs it. A simple way to do this is with the script command. In its simplest form:

script -c myprogram /dev/null >/dev/null

When myprogram runs and opens /dev/tty, this is a terminal provided by script, not the terminal in which script runs. What script does when it detects a write on the terminal is to both write to its own standard output and write to the indicated typescript file; hence I set both script's standard output and the typescript file to /dev/null.

If myprogram reads from the terminal, script reads from its own standard input, so you'll probably want to redirect this to /dev/null as well.

Note that script does not pass the exit status of myprogram to its caller. Some implementations (e.g. the one in Debian and derivatives) have a -e option to do that.

3
  • 1
    Many thanks! The answer covers everything I need (exit status etc.). I didn't know the existence of script. – Firmin Martin May 3 at 12:40
  • Interesting. Essentially, /dev/tty is also an abstraction layer, which can be exploited. – Peter - Reinstate Monica May 4 at 11:20
  • @Peter-ReinstateMonica: Right, it's "magic", not a real fixed device like your /dev/ttyS0 serial port or /dev/tty1 text console terminal: opening it depends on the state of something else (your controlling TTY). So in that respect it's like /dev/stdout. – Peter Cordes May 4 at 12:28
0

It's very unusual that a program would open /dev/tty itself. If you need to print something to the console, you'd just write to standard output, stdout, which you could redirect, as Gilles shows.

Your only choice here would be intercepting the libc fopen call, unless that's been inlined (which isn't that rare) or the underlying operating system open call and bend it.

It's not that hard. You'd need to write a small library that contains said open function, which in turn calls the actual open function after having "sanitized" its input (i.e., if the file name is /dev/tty, replace it with /dev/null).

Run program and intercept and redirect syscalls shows how that's done.

5
  • As Gilles shows, you can “redirect” /dev/tty, by changing the program’s controlling terminal. – Stephen Kitt May 3 at 12:49
  • Thanks for the insight, I understand what you mean though it's not what I'm looking for. The program I'm dealing with is Git. See here. – Firmin Martin May 3 at 12:50
  • 5
    Um, that feels like an XY problem: are you sure you want to test an interactive git when you're redirecting tty to /dev/null? Wouldn't that sound like you want to use git non-interactively, which you can achieve through easier means? – Marcus Müller May 3 at 13:16
  • 2
    It is not unusual at all to open /dev/tty for interactive programs. – Peter - Reinstate Monica May 4 at 11:09
  • @Peter-ReinstateMonica absolutely, but that's usually the job of things like readline or ncurses, and then the solution to working without their output is configuring them accordingly, or preloading different implementations of their functionality alltogether. – Marcus Müller May 4 at 11:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.