Reputation: 50298
I am doing standard redirection:
$ cat file.txt | /usr/bin/program
But the program behaves differently if I run it directly in terminal and copy-paste input. It displays a progress bar when the input is a terminal. I would like to have the progress bar anyway.
In short, how can I "cheat" the program that the input comes from the terminal and is not redirected from a file?
Upvotes: 3
Views: 625
Reputation: 754080
It may be simplest to use the expect
program; it does most of the necessary work for you.
The necessary work is fiddly. It involves using pseudo-ttys, which are devices that look to programs like terminals. If you're going to roll your own, then the POSIX system calls you need to know about are:
The posix_openpt()
interface is relatively new (Issue 6, compared with Issue 4, Version 2 for the other functions listed). If your system doesn't have posix_openpt()
, you need to get yourself one of the Unix books (Stevens or Rochkind, probably) to find out how else to do open the master side of a pty, or read your system manuals rather carefully. However, the rationale for posix_openpt()
at the link above may also help — it also has guidelines for using the other functions. Linux has posix_openpt()
; so does Mac OS X and by inference the BSD systems generally.
Books:
W Richard Stevens, Stephen A Rago Advanced Programming in the Unix Environment, 3rd Edn
Marc J Rochkind Advanced Unix Programming, 2nd Edn
Upvotes: 5
Reputation: 158040
I assume that the program will call the glibc function isatty()
to check whether stdin/stdout is a terminal or not. That's common for programs which use colorized output on terminals or other features of an ANSI terminal like cursor positioning or line erasing / redrawing.
You can trick the program using the LD_PRELOAD environment variable. LD_PRELOAD is handled by the ELF linker and tells that a dynamic library should be loaded before all others. Using this feature it is possible to override library functions, in your case the glibc function isatty()
.
Here comes an example:
libisatty.c
/**
* Overrides the glibc function. Will always return true.
*
* Note: Although this should be ok for most applications it can
* lead to unwanted side effects. It depends on the question
* why the programm calls isatty()
*/
int isatty(int param) {
return 1;
}
Makefile
# Make the shared Library
lib: libisatty.c
gcc -shared -Wl,-soname,libisatty.so.1 -o libisatty.so.1.0 libisatty.c
ln -s libisatty.so.1.0 libisatty.so.1
ln -s libisatty.so.1 libisatty.so
Run:
make lib
It should build fine, I've tested it on Ubuntu12.04 AMD 64.
Now it's time to test the library. :) I've used the command ls --color=auto
for tests. ls
calls isatty()
to decide whether it should colorize it's output or not. If the output is redirected to a file or a pipe it won't be colorized. You can test this easily using the following commands:
ls --color=auto # should give you colorized output
ls --color=auto | cat # will give you monochrome output
Now we'll try the second command again using the LD_PRELOAD environment var:
LD_PRELOAD=libisatty.so ls --color=auto | cat
You should see colorized output.
Upvotes: 3
Reputation: 100051
You need to use a pseudo-tty to have the effect you desire. 'man pty' will tell you more about it.
Upvotes: 3