Hi all,

As seen in NetBSD, FreeBSD and Linux, script(1) could do with a way to
tell it what command to run instead of your $SHELL.  This implements
the "-c command" option.  I've taken the logic to start the command
(and its arguments, if any) from crontab(1), execv'ing `sh -c
<command>`.

I wrote this because I got fed up with typing `cu -l cuaU3 -s 19200`
right after starting script every time: it annoys my command line
editing fingers that I can't just recall what I did before.

There's a roundabout way of achieving something similar by setting
SHELL to some script that runs your command with its arguments, but
that's just silly (and nasty).

NetBSD: uses "-c command", executes the command using system(3)
Linux: uses "-c command", didn't look at the implementation
FreeBSD: uses arguments after the filename, wields execvp(3)

(these three have a bunch more extra options, all of which mostly look
like bullshit - specifying an alternative command seems the only
useful thing to me)

Illumos: feature parity with current OpenBSD, no -c command


My implementation worked from the get go, so there must be something
wrong with it.  All comments and feedback appreciated; asbestos
underwear at the ready.

Sample output:
[weerd@pom] $ obj/script -c "ls -l" output.`date +%s`
Script started, output file is output.1513183391
total 36
drwxr-xr-x  2 weerd  wsrc   512 May  9  2017 CVS
-rw-r--r--  1 weerd  wsrc   131 Sep 21  1997 Makefile
lrwxrwx---  1 weerd  wsrc    23 Dec 13 17:42 obj -> /usr/obj/usr.bin/script
-rw-r--r--  1 weerd  wsrc     0 Dec 13 17:43 output.1513183391
-rw-r--r--  1 weerd  wsrc  3642 Dec 13 17:42 script.1
-rw-r--r--  1 weerd  wsrc  8464 Dec 13 17:41 script.c
Script done, output file is output.1513183391


Paul 'WEiRD' de Weerd

Index: script.1
===================================================================
RCS file: /cvs/src/usr.bin/script/script.1,v
retrieving revision 1.14
diff -u -p -r1.14 script.1
--- script.1    15 Jan 2012 20:06:40 -0000      1.14
+++ script.1    13 Dec 2017 12:27:32 -0000
@@ -39,6 +39,7 @@
 .Sh SYNOPSIS
 .Nm script
 .Op Fl a
+.Op Fl c Ar command
 .Op Ar file
 .Sh DESCRIPTION
 .Nm
@@ -65,6 +66,13 @@ Append the output to
 or
 .Pa typescript ,
 retaining the prior contents.
+.It Fl c Ar command
+Run
+.Ar command
+instead of an interactive shell.
+To run a
+.Ar command
+with its own arguments, enclose it in quotes.
 .El
 .Pp
 The script ends when the forked shell exits (a control-D
Index: script.c
===================================================================
RCS file: /cvs/src/usr.bin/script/script.c,v
retrieving revision 1.33
diff -u -p -r1.33 script.c
--- script.c    12 Apr 2017 14:49:05 -0000      1.33
+++ script.c    13 Dec 2017 12:15:20 -0000
@@ -89,7 +89,7 @@ int           istty;
 
 __dead void done(int);
 void dooutput(void);
-void doshell(void);
+void doshell(char *);
 void fail(void);
 void finish(int);
 void scriptflush(int);
@@ -102,15 +102,20 @@ main(int argc, char *argv[])
        struct sigaction sa;
        struct winsize win;
        char ibuf[BUFSIZ];
+       char *cmd;
        ssize_t cc, off;
        int aflg, ch;
 
+       cmd = NULL;
        aflg = 0;
-       while ((ch = getopt(argc, argv, "a")) != -1)
+       while ((ch = getopt(argc, argv, "ac:")) != -1)
                switch(ch) {
                case 'a':
                        aflg = 1;
                        break;
+               case 'c':
+                       cmd = optarg;
+                       break;
                default:
                        fprintf(stderr, "usage: %s [-a] [file]\n", __progname);
                        exit(1);
@@ -163,7 +168,7 @@ main(int argc, char *argv[])
                if (child)
                        dooutput();
                else
-                       doshell();
+                       doshell(cmd);
        }
 
        bzero(&sa, sizeof sa);
@@ -302,9 +307,10 @@ scriptflush(int signo)
 }
 
 void
-doshell(void)
+doshell(char *cmd)
 {
        char *shell;
+       char *argp[] = {"sh", "-c", NULL, NULL};
 
        shell = getenv("SHELL");
        if (shell == NULL)
@@ -313,8 +319,15 @@ doshell(void)
        (void)close(master);
        (void)fclose(fscript);
        login_tty(slave);
-       execl(shell, shell, "-i", (char *)NULL);
-       warn("%s", shell);
+
+       if (cmd != NULL) {
+               argp[2] = cmd;
+               execv(_PATH_BSHELL, argp);
+               warn("unable to execute %s", _PATH_BSHELL);
+       } else {
+               execl(shell, shell, "-i", (char *)NULL);
+               warn("%s", shell);
+       }
        fail();
 }
 

-- 
>++++++++[<++++++++++>-]<+++++++.>+++[<------>-]<.>+++[<+
+++++++++++>-]<.>++[<------------>-]<+.--------------.[-]
                 http://www.weirdnet.nl/                 

Reply via email to