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