Here's a diff to make script(1) read input from a file when "-i" flag is
used (and fallback to stdin when file is out of data).
Can be used to emulate user input for interactive programs.

(here we do tab completion)

[/tmp]% cat test 
ls mutt-                <-- two tabs here
exit
[/tmp]% script -i test > /dev/null
[/tmp]% cat typescript 
Script started on Thu May 19 15:21:42 2011
ls mutt-                
exit
[/tmp]% ls mutt-watashi-1000-24241-  
mutt-watashi-1000-24241-672795505315738224 <-- tab completion
mutt-watashi-1000-24241-796843985399926878 <-- in action             
[/tmp]% ls mutt-watashi-1000-24241-
ls: mutt-watashi-1000-24241-: No such file or directory
[/tmp]% exit

Script done on Thu May 19 15:21:42 2011

The manpage change is not very clean and descriptive, but well..

Index: usr.bin/script/script.1
===================================================================
RCS file: /cvs/src/usr.bin/script/script.1,v
retrieving revision 1.13
diff -u -p -u -r1.13 script.1
--- usr.bin/script/script.1     31 May 2007 19:20:15 -0000      1.13
+++ usr.bin/script/script.1     19 May 2011 11:09:37 -0000
@@ -38,7 +38,8 @@
 .Nd make typescript of terminal session
 .Sh SYNOPSIS
 .Nm script
-.Op Fl a
+.Op Fl ai
+.Op Ar infile
 .Op Ar file
 .Sh DESCRIPTION
 .Nm
@@ -65,6 +66,12 @@ Append the output to
 or
 .Pa typescript ,
 retaining the prior contents.
+.El
+.Pp
+.Bl -tag -width Ds
+.It Fl i
+Read commands from 
+.Ar infile .
 .El
 .Pp
 The script ends when the forked shell exits (a control-D
Index: usr.bin/script/script.c
===================================================================
RCS file: /cvs/src/usr.bin/script/script.c,v
retrieving revision 1.25
diff -u -p -u -r1.25 script.c
--- usr.bin/script/script.c     27 Oct 2009 23:59:43 -0000      1.25
+++ usr.bin/script/script.c     19 May 2011 11:09:37 -0000
@@ -104,16 +104,21 @@ main(int argc, char *argv[])
        struct winsize win;
        char ibuf[BUFSIZ];
        ssize_t cc, off;
-       int aflg, ch;
+       int aflg, iflg, ch, ifd;
+       char *ifname;
 
-       aflg = 0;
-       while ((ch = getopt(argc, argv, "a")) != -1)
+       aflg = iflg = 0;
+       while ((ch = getopt(argc, argv, "ai:")) != -1)
                switch(ch) {
                case 'a':
                        aflg = 1;
                        break;
+               case 'i':
+                       iflg = 1;
+                       ifname = optarg;
+                       break;
                default:
-                       fprintf(stderr, "usage: %s [-a] [file]\n", __progname);
+                       fprintf(stderr, "usage: %s [-ai] [infile] [outfile]\n", 
__progname);
                        exit(1);
                }
        argc -= optind;
@@ -126,6 +131,8 @@ main(int argc, char *argv[])
 
        if ((fscript = fopen(fname, aflg ? "a" : "w")) == NULL)
                err(1, "%s", fname);
+       if (iflg && ((ifd = open(ifname, O_RDONLY)) == -1))
+               err(1, "%s", ifname);
 
        (void)tcgetattr(STDIN_FILENO, &tt);
        (void)ioctl(STDIN_FILENO, TIOCGWINSZ, &win);
@@ -133,6 +140,8 @@ main(int argc, char *argv[])
                err(1, "openpty");
 
        (void)printf("Script started, output file is %s\n", fname);
+       if (iflg)
+               (void)printf("Input file is %s\n", ifname);
        rtt = tt;
        cfmakeraw(&rtt);
        rtt.c_lflag &= ~ECHO;
@@ -168,11 +177,16 @@ main(int argc, char *argv[])
        while (1) {
                if (dead)
                        break;
-               cc = read(STDIN_FILENO, ibuf, BUFSIZ);
+               cc = read(iflg ? ifd : STDIN_FILENO, ibuf, BUFSIZ);
                if (cc == -1 && errno == EINTR)
                        continue;
-               if (cc <= 0)
+               if (cc <= 0) {
+                       if (iflg) {
+                               iflg = 0;
+                               continue;
+                       }
                        break;
+               }
                for (off = 0; off < cc; ) {
                        ssize_t n = write(master, ibuf + off, cc - off);
                        if (n == -1 && errno != EAGAIN)
@@ -303,7 +317,6 @@ doshell(void)
 void
 fail(void)
 {
-
        (void)kill(0, SIGTERM);
        done(1);
 }
-- 
Alexander Polakov | plhk.ru

Reply via email to