On Thu, Jan 02, 2003 at 03:16:54PM -0800, Tim Kientzle wrote:
> Paul Schenkeveld wrote:
> 
> > If people think that -q is a good option for printenv, I can come up
> > with a patch for the standard printenv.  Opinions?
> 
> 
> Some form of unambiguous output from printenv
> would be nice.  I would suggest quoting both the
> variable name and the value just to be on the safe side.
> 
> Even better:  modify 'env' to support
> that format as input.  Then you could
> use, e.g.,
>    printenv -q >saved_environment
> to record the environment and then use
>    env - -r saved_environment <command>
> to recreate that environment.

I've rolled a patch for a recent -STABLE printenv (see below).
Comments?  Anyone care to commit this?

Will see if I can do a patch for env over the weekend.

-- 
Paul Schenkeveld, Consultant
PSconsult ICT Services BV

--- /usr/src/usr.bin/printenv/printenv.1        Wed Jun 26 10:25:30 2002
+++ src/printenv/printenv.1     Fri Jan  3 02:14:11 2003
@@ -42,6 +42,9 @@
 .Nd print out the environment, set and print environment
 .Sh SYNOPSIS
 .Nm
+.Op Fl e
+.Op Fl q
+.Op Fl Q
 .Op Ar name
 .Nm env
 .Op Fl
@@ -81,6 +84,17 @@
 .Pp
 The options are as follows:
 .Bl -tag -width indent
+.It Fl e
+Output
+.Nm export
+commands for every environment variable.
+.It Fl q
+Double quote the value of every environment variable,
+special characters ("\\`$) will be preceeded bay a backslash.
+.It Fl Q
+Like
+.Fl q
+but also quote the name of the variable.
 .It Fl i
 Execute the
 .Ar utility
--- /usr/src/usr.bin/printenv/printenv.c        Sat Mar 29 05:31:36 1997
+++ src/printenv/printenv.c     Fri Jan  3 02:18:32 2003
@@ -49,6 +49,8 @@
 #include <unistd.h>
 
 void   usage __P((void));
+void   print_var __P((char *, int));
+void   print_quoted __P((char *));
 
 /*
  * printenv
@@ -62,12 +64,25 @@
        char *argv[];
 {
        extern char **environ;
-       register char *cp, **ep;
+       register char *cp, **ep, *eq;
        register size_t len;
        int ch;
+       int flags = 0;
+#define        eFLAG   1
+#define        qFLAG   2
+#define        QFLAG   4
 
-       while ((ch = getopt(argc, argv, "")) != -1)
+       while ((ch = getopt(argc, argv, "eqQ")) != -1)
                switch(ch) {
+               case 'e':
+                       flags |= eFLAG;
+                       break;
+               case 'q':
+                       flags |= qFLAG;
+                       break;
+               case 'Q':
+                       flags |= qFLAG | QFLAG;
+                       break;
                case '?':
                default:
                        usage();
@@ -76,8 +91,18 @@
        argv += optind;
 
        if (argc == 0) {
-               for (ep = environ; *ep; ep++)
-                       (void)printf("%s\n", *ep);
+               for (ep = environ; *ep; ep++) {
+                       if (flags & eFLAG) {
+                               for (eq = *ep; *eq && *eq != '='; )
+                                       eq++;
+                               printf("export %s%.*s%s; ",
+                                       flags & QFLAG ? "\"" : "",
+                                       eq - *ep,
+                                       *ep,
+                                       flags & QFLAG ? "\"" : "");
+                       }
+                       print_var(*ep, flags);
+               }
                exit(0);
        }
        len = strlen(*argv);
@@ -85,7 +110,12 @@
                if (!memcmp(*ep, *argv, len)) {
                        cp = *ep + len;
                        if (!*cp || *cp == '=') {
-                               (void)printf("%s\n", *cp ? cp + 1 : cp);
+                               if (flags & qFLAG) {
+                                       print_quoted(*ep);
+                                       putchar('\n');
+                               }
+                               else
+                                       (void)printf("%s\n", *cp ? cp + 1 : cp);
                                exit(0);
                        }
                }
@@ -93,8 +123,50 @@
 }
 
 void
+print_var(var, flags)
+       char *var;
+       int flags;
+{
+       register char *eq;
+       for (eq = var; eq && *eq && *eq != '='; )
+               eq++;
+       if (*eq == '=') {
+               *eq++ = '\0';
+               if (flags & QFLAG)
+                       print_quoted(var);
+               else
+                       printf("%s", var);
+               putchar('=');
+               if (flags & qFLAG)
+                       print_quoted(eq);
+               else
+                       printf("%s", eq);
+               putchar('\n');
+       }
+}
+
+void
+print_quoted(str)
+       char *str;
+{
+       putchar('"');
+       for ( ; *str; str++)
+               switch (*str) {
+               case '\\':
+               case '"':
+               case '`':
+               case '$':
+                       putchar('\\');
+                       /* FALL THRU */
+               default:        
+                       putchar(*str);
+               }
+       putchar('"');
+}
+
+void
 usage()
 {
-       (void)fprintf(stderr, "usage: printenv [name]\n");
+       (void)fprintf(stderr, "usage: printenv [-eqQ] [name]\n");
        exit(1);
 }

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message

Reply via email to