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