Dos and/or Windows versions of Unix SCRIPT command

5

2

Back in university, when we had to submit an assignment in CS, we would have to perform a series of steps including running script, date, whoami, etc., and then running our program.

The script command would pipe all text sent to the display to both the display and a specified file as well.

Ever since, I have been looking for a Dos and/or Windows version, but have come up empty. Some programs can be redirected to a file, but then the display is not echoed, and some programs don’t seem to work with redirection at all.

Any ideas?


Edit:

So far, the answers that I’ve gotten seem to work exactly like the standard redirection commands (<, >, |). These do not work with all programs. For example, the Microsoft C++ compiler CL.EXE. If you run cl /? through a redirection command or pipe it through another program (such as TEE), you will not get the header/banner text.

Another example is a program I wrote a while back in Pascal (I think the last compile was in FreePascal). The help text does not get redirected at all. I have seen this occur with other programs as well like MKISOFS. It has a long help text, but cannot be paused by piping it through MORE or redirected to a file!

I have wondered about this for many years. I used to think that it may be because the text is being written directly to the screen (eg port B800) or something, but I have yet to pin down the cause, let alone find a program that can do this job.

Synetech

Posted 2009-08-01T20:56:31.033

Reputation: 63 242

Answers

2

Okay, so as usual, I took it upon myself to write the program. I had a bit of free time tonight and threw together a native (ie, non-Cygwin) test program that works exactly as I had hoped, albeit with two limitations. (I don’t have an always-on host, but I’ll see to cleaning up the program, writing docs, and releasing it.)

  1. It cannot capture output from programs that write directly to the video hardware (or virtualized hardware as the case may be), so the Pascal program I mentioned cannot be captured unless I recompile it without the direct flag set—which incidentally became unnecessary when I recompiled it with FreePascal.

  2. It cannot receive input from stderr. For example, if you execute cl /? | script.exe c:\test.log, only the help text of the Microsoft compiler will be sent to the file; the banner will only be displayed on the screen. (This is somewhat baffling due to the way the program works, so I’m going to look into it.)

There’s little that can be done about problem (1) (I would not be surprised if there were some clever person somewhere who could figure out a way to intercept direct screen writes, but for all intents and purposes, it’s probably unlikely.)

Problem (2) can be worked around by redirecting stderr to stdout before piping it as follows. It’s not pretty (or as convenient, but it works).

cl /? 2>&1| script.exe c:\test.log

It may/should also be workable from program’s side, thus simplifying the pipe, but I have yet to find any information on how (at least in a “normal/official” way, eg via C++). I do have an idea about installing an interrupt handler in the interrupt vector table to intercept calls to the common ouput API functions, which may/probably will work. In fact, in 1998, I had written an experimental DOS TSR (that also works in the Windows NTVDM), which intercepts output functions and colors them (ie, generic syntax-coloring) before sending them to the screen. It would/should be easy to adapt it to also send a copy to a file.

enter image description here

Synetech

Posted 2009-08-01T20:56:31.033

Reputation: 63 242

If you try to intercept direct screen writes, you're bound to have compatibility problems. Better approach may be to use a TSR that can read the screen contents. I do bet screen capture programs work. Capture the info after it is written, rather than before it is written, and you'll probably have less compatibility issues. Is 20CC available? I find the grey background hideous, but the concept is intriguing. If it's customizable (gotta love source code), I'd be interested enough to snag a copy. Did a quick search online and didn't find it yet. – TOOGAM – 2015-02-14T07:28:27.707

Looking at that screen again, it looks super buggy. :( "Largest availabel upper memory bemory", and "0 bytes available contiguous extended m". And how many bytes are used by the "MS-DOS resident in High Memory Area?" It looks like some hyphens have been moved. This happened twice; in both cases, they should be under the words "Size in Hex", but look like they overwrote yet more information. – TOOGAM – 2015-02-16T15:59:25.277

Have you been using it for a while and does it work reliably (no serious bugs that haven't been ironed out due to lack of time/interest)? Could you perhaps edit your answer to provide a link to the program's source code if you still have it? I'm looking for the same thing (a port of tee). – Agi Hammerthief – 2015-09-25T22:16:16.080

(Technically this is actually a port of tee, not script, but it’ll have to do.) – Synetech – 2013-10-18T02:08:15.683

2

Take a look at Cygwin, it gives you access to all those great UNIX command line tools in Windows.

Frank Szczerba

Posted 2009-08-01T20:56:31.033

Reputation: 505

Thanks, but it has the same problem that I explained in the comment to akf’s answer. – Synetech – 2009-08-04T16:54:18.823

1

Unfortunately, it seems that you won't have luck finding an out-of-the-box Microsoft solution. You can check out a similar post on StackOverflow. The digest:

akf

Posted 2009-08-01T20:56:31.033

Reputation: 3 781

1I tried them out. Unfortunately they do not work any better than standard redirection.

For example, the MS C++ compiler CL.exe. If you run <code>cl /?</code> and run it through < or > or | or TEE or anything else, then you will only get the output from the options on, not the header text. – Synetech – 2009-08-04T16:53:48.777

6You probably don't get the header text because it is sent STDERR. You'll have to redirect both STDOUT (>) and STDERR (2>). – Ludwig Weinzierl – 2009-08-04T17:30:16.867

1Neither of those redirects work (as is) because they would wipe out the exe file (I’m not asking about redirecting to a file; I’m asking about the script command). You need to use 2>&1| to pipe it instead. – Synetech – 2011-08-31T05:02:59.203

3FYI, this is how you redirect both STDERR and STDOUT for cl.exe: cl /? >output.log 2>&1 – Leftium – 2009-11-14T08:12:14.583

1

I found a Cygwin port of the Unix script command. It captures both STDOUT and STDERR (so it gets the header output from cl.exe).

However capturing cmd.exe commands is a little convoluted for two reasons:

  • script spawns a cygwin bash shell (not cmd.exe)
  • script does not work when started from a cmd.exe shell; it must be started from cygwin.

You can do it, though:

  1. open a cygwin shell.
  2. start script
  3. start a cmd.exe shell from within the cygwin shell
  4. do your stuff in cmd.exe
  5. exit out of cmd.exe
  6. exit out of script

*also the cmd.exe shell spawned from inside cygwin acts a little strange, but the commands seem to work:

  • the window that usually pops up if you try to run cl.exe without first running vcvars32.bat does not come up
  • console input is very finicky (for example typing LEFT RIGHT cl or UP cl does not work.)

Leftium

Posted 2009-08-01T20:56:31.033

Reputation: 8 163

Thank wonsungi. I eventually managed to get the script.exe util from Cygwin to work, but I still have the same problem.

I was able to get both parts of CL’s output to redirect to a file with either script.exe or the redirection syntax you listed above. Unfortunately, there are still programs that output text to the screen that still do not get redirected by any of these.

One such program is a Pascal app I wrote some time back (it prints using the standard writeln). The current one was compiled with either Free Pascal or Turbo Pascal; I’ll have to check and try both. – Synetech – 2009-11-14T18:03:02.487

1

This General Pascal FAQ explains the cause, as well as a solution for Turbo Pascal programs.

Q. When I redirect the screen output of my programs to a file the file is empty and the output still appears on the screen. What am I doing wrong?

A. You are probably using the CRT unit and its default method of writing to stdout is by direct screen writes. In order to enable output to be redirected all writes must be done by DOS. Setting the variable DirectVideo to false has no effect on redirection as all it does is use the BIOS for screen writes - not DOS.

To enable redirection you must not use the CRT unit

OR

assign(output,'');
rewrite(output);

This will make all output go through DOS and thus can be redirected if desired. To restore the default situation:

AssignCRT(output);
rewrite(output);

Leftium

Posted 2009-08-01T20:56:31.033

Reputation: 8 163

Thanks for the link to the FAQ.

I checked my sources and it seems that you are correct. The version of the program that I use was compiled back when I had the CRT unit included, so it doesn’t redirect. The current version does not include the CRT unit (in fact it is commented out, apparently because I had discovered it was the cause of the redir problem before but forgot). I compiled and tested the latest version and it redirects correctly.

As for the other apps like CL, it seems you were both correct, it redirs to STDERR, so now I can use the SCRIPT.exe command as expected.

Thanks. – Synetech – 2009-11-15T17:50:30.050

1

Many alternatives to CMD make life easier on many fronts, including solve the problem you have indicated of the missing script command. I used PowerCMD and it redirects the output to it's log folder by default. So as an end user you will see the commands as you type and the errors and output of the commands while simultaneously all your work is being "logged" in a log file.

To configure it in PowerCMD go to File --> Preference --> Auto Save.

Snippet from the log file that is being automatically populated as I work on PowerCMD,

c:\Software\Microsoft\SysinternalsSuite>date
The current date is: Fri 02/13/2015 
Enter the new date: (mm-dd-yy) 
c:\Software\Microsoft\SysinternalsSuite>someBadCommand
'someBadCommand' is not recognized as an internal or external command,
operable program or batch file.

Yazad

Posted 2009-08-01T20:56:31.033

Reputation: 111

0

This is really two questions in one, one for DOS and one for Windows, albeit that the answer is the same for both.

It it simply not possible for such a program to exist.

There are two basic variants of script on Unices and on Linux. One (such as this Linux version) uses pipes, the other (such as this HP/UX version) uses pseudo-terminals to avoid the problems with TUI programs that present "full screen" interfaces that the pipe approach has. Windows NT simply does not have a pseudo-terminal mechanism. It is simply not possible to capture the I/O to and from a console on Windows NT as it is with pseudo-terminals on POSIX systems. One could use the pipe approach, but …

  • … DOS doesn't have a pipe mechanism. (Don't be confused by what you can do in DOS command interpreters. Those are not pipes.)
  • … on Windows NT it will suffer from the problems — much the same as for the pipe approach on Unices and Linux — that …
    • … some programs will recognize that their standard output is not a console and act differently.
    • … other programs that treat the pipe like a console will fail, because pipe devices don't support the console-specific system calls.

Cygwin relies upon the coöperation of the target programs in a collective pretense.

You might be wondering about the Cygwin script command, and why it has the not-quite-right behaviour with non-Cygwin programs that it has.

Cygwin tries to emulate pseudo-terminals, using Windows NT pipes. It relies upon the fact that every Cygwin program uses a Cygwin runtime library that "knows" when a pipe is "really" a pseudo-terminal, using information private to the Cygwin runtime library, and acts accordingly. The runtime library's isatty() function says "yes" when the runtime sees a pipe that is "really" a Cygwin pseudo-terminal. So Cygwin programs run by Cygwin's script will act as if they are connected to (pseudo-)terminals.

Of course, non-Cygwin programs, that don't participate in this collective delusion, will just see the pipes as they truly are, as pipes, and behave as they do when their standard inputs/outputs/errors are pipes.

JdeBP

Posted 2009-08-01T20:56:31.033

Reputation: 23 855

Cygwin is a step in the right direction, but there are other third-party command-prompts that can provide the necessary functionality. After all, it is simply a matter of sending the output to both a file and the screen. Since a third-party command-prompt would be responsible for painting the screen, it receives the input and can simply send a copy to a file. The problem is that it is not easy to do this with the default command-prompt in Windows. As for DOS, it can work if the program uses the default print functions (eg, DOS INT 2F) as opposed to writing directly to the screen. – Synetech – 2011-08-27T19:34:05.237

Kiddo, a command prompt isn't a program. A command interpreter is a program, and it doesn't "paint the screen" for other programs or indeed handle their I/O in any way. Your idea that this is possible is based upon a quite erroneous idea of what does what in Windows. And you're living in 1986 with respect to DOS. That's what people said then, and it didn't happen that way.

– JdeBP – 2011-08-28T00:21:30.397

I’m tried of arguing this. When I get some time, I’m just going to write a script.exe myself; I’ve already got no less than two methods to use in mind. – Synetech – 2011-08-29T04:12:42.937