3

I have a utility foo that I want to grep output from, redirect, and otherwise do all the normal text manipulation stuff. But alas! Look at what it does...

$ foo
bar
$ foo > /dev/null
bar
$ foo 2> /dev/null
bar
$ foo | grep abc
bar
$ foo 2| grep abc
bar

Apparently the output is neither stdout nor stderr. Perhaps foo rights directly to the tty instead of to stdout. There is an answer here that provides a workaround using script -c. But alas again!

$ script -c foo > /dev/null
script: illegal option -- c
usage: script [-a] [file]

Perhaps my script utility is not the full version. The operating system is QNX.

For those of us who cannot use the script -c workaround, how can we easily capture the output? Is there a way to redirect the tty file itself, if that makes any sense?

Is it possible to do something like foo (/dev/ttyp0)| grep abc? That likely will not work exactly as shown, but is there a way to do something similar? An answer which requires the file to be redirected first (if that is even possible) is fine, so something like /dev/ttyp0 please go to /dev/null ; foo is ok.

Ultimately, I would like to be able to pipe the output of foo to grep and/or redirect foo output to a file.

Aaron
  • 187
  • 1
    Try SHELL=/your/program script .... –  Jun 14 '19 at 23:54
  • also, if script insists to run /bin/sh or your login shell, it could tricked via the ENV variable to source a file with calls exec /your/program. What is the shell on qnx? –  Jun 14 '19 at 23:55
  • If /your/program doesn't accept or interprets the -i option specially, you could write a wrapper for it. –  Jun 14 '19 at 23:57
  • @mosvy That's an interesting idea. One would possibly have to strip the header and footer off from the output of script if that works. Unfortunately I don't have a QNX system to test on. – Kusalananda Jun 15 '19 at 00:21

3 Answers3

2

Yes, the foo application is likely writing directly to the TTY.

Here's a script that does the same thing:

#!/bin/sh
echo 'bar' >$(tty)

Since your script utility can't be used to execute foo directly (only through the interactive shell that the utility starts), you will have to find another way of allocating a new TTY for the execution of the command.

One such way is using ssh:

ssh -t localhost "$PWD/foo" >output.log

This would (ab)use ssh to connect to localhost, forcing the allocation of a TTY with -t, and running the foo application located in the current directory. The output of foo, including everything that was written te the TTY, to standard output and to standard error, would come back to you from the standard output of ssh, and you may then redirect it to wherever you want.

Kusalananda
  • 333,661
  • This does indeed work, thank you! My capture still is not working, but for unrelated reasons. Your suggestion is straightforward, simple, and did just as advertised. – Aaron Jun 17 '19 at 20:05
0

OK I use script (on a BSD box) to capture the output of long runs of jobs, or build output. This is, I believe what you're running into. For example, from the man page:

-a      Append the output to file or typescript, retaining the prior contents.

look familiar? :)

The option -F pipe may provide you with a possible solution. But in the end, I'm not really sure, judging by your question, that script is actually what you were looking for.

Have a look at the man page I linked to.

HTH

somebody
  • 343
  • 2
    The user is on QNX. This is the manual for script on QNX: http://www.qnx.com/developers/docs/7.0.0/#com.qnx.doc.neutrino.utilities/topic/s/script.html They want to execute the foo thing directly and pipe or redirect the output somewhere. You can't use QNX script to do that as it needs to run an interactive shell session. – Kusalananda Jun 14 '19 at 23:56
  • Ugh. Sorry. I saw the output from the OPs "solution", and looked exactly like the output from the man page I linked to. Thanks for the clarification, Kusalananda! – somebody Jun 15 '19 at 00:04
0

If your program ignores the -i option, you can run it directly with

SHELL=/path/to/your/program script /dev/null > output 

If it chokes on the -i option, you can create a wrapper for it.

$ cat wrapper
#! /bin/sh
exec /path/to/your/program
$ chmod 755 wrapper
$ SHELL=./wrapper script /dev/null > output