On Sat, Dec 09, 2017 at 06:44:44PM +0100, Theo Buehler wrote:
> This was discussed in a smaller circle and has been in snaps for two
> days, but I'd like to show this to a wider audience.
> 
> Theo asked me to make sure that all our shells print a prompt including
> the hostname by default. The reasoning is roughly as follows:
> 
> With tmux, ssh and vmd, we tend to open shells on many different hosts
> simultaneously and the default prompts '$ ' and '# ' for {,k}sh as well
> as  '% ' and '# ' for csh become dangerous: it's very easy to issue a
> command on the wrong host.
> 
> This can easily be avoided by displaying the hostname in the prompt.
> Everything beyond "hostname{$,#,%} " is going to be a matter of taste,
> so we left it at that. If you use an FQDN, only the first part (the
> output of 'hostname -s') will be printed.
> 
> Since not everybody makes use of the config files in /etc/skel or runs
> only login shells, it is not really possible to handle this with config
> files. Thus, we decided to hardcode it in the shells. We are aware that
> POSIX says that PS1 defaults to '$ ' or '# ' for sh(1).
> 
> The simplest case is ksh: rely on the already existing shell escapes.
> For sh we can easily fall back to these (the diff to ksh/lex.c).  For
> csh, I decided to implement the "%m" prompt escape which is standard in
> c-type shells, so I don't expect this to cause surprises.
> 
> In single user mode and the early installer, gethostname() returns the
> empty string, so the familiar prompts will be displayed there.

I think we should go ahead with this for the reasons mentioned, the
default configuration should make things easier for the people using it,
which means developers doing release builds, spinning up vms, etc.

People can go on and on about standards compliance, but if it means
someone is less likely to reboot the wrong machine, or worse, then
POSIX be damned.

ok brynet@

> Index: bin/csh/const.c
> ===================================================================
> RCS file: /var/cvs/src/bin/csh/const.c,v
> retrieving revision 1.8
> diff -u -p -r1.8 const.c
> --- bin/csh/const.c   26 Oct 2015 16:27:04 -0000      1.8
> +++ bin/csh/const.c   8 Dec 2017 12:15:26 -0000
> @@ -114,6 +114,8 @@ Char STRprintexitvalue[] = { 'p', 'r', '
>                           'a', 'l', 'u', 'e', '\0' };
>  Char STRprompt[]     = { 'p', 'r', 'o', 'm', 'p', 't', '\0' };
>  Char STRprompt2[]    = { 'p', 'r', 'o', 'm', 'p', 't', '2', '\0' };
> +Char STRpromptroot[] = { '%', 'm', '#', ' ', '\0' };
> +Char STRpromptuser[] = { '%', 'm', '%', ' ', '\0' };
>  Char STRpushdsilent[]        = { 'p', 'u', 's', 'h', 'd', 's', 'i', 'l', 
> 'e', 'n',
>                           't', '\0' };
>  Char STRret[]                = { '\n', '\0' };
> @@ -138,8 +140,6 @@ Char STRspor2sp[] = { ' ', '|', '|', ' '
>  Char STRsporsp[]     = { ' ', '|', ' ', '\0' };
>  Char STRstar[]               = { '*', '\0' };
>  Char STRstatus[]     = { 's', 't', 'a', 't', 'u', 's', '\0' };
> -Char STRsymcent[]    = { '%', ' ', '\0' };
> -Char STRsymhash[]    = { '#', ' ', '\0' };
>  Char STRterm[]               = { 't', 'e', 'r', 'm', '\0' };
>  Char STRthen[]               = { 't', 'h', 'e', 'n', '\0' };
>  Char STRtilde[]              = { '~', '\0' };
> Index: bin/csh/csh.c
> ===================================================================
> RCS file: /var/cvs/src/bin/csh/csh.c,v
> retrieving revision 1.41
> diff -u -p -r1.41 csh.c
> --- bin/csh/csh.c     30 Aug 2017 06:42:21 -0000      1.41
> +++ bin/csh/csh.c     8 Dec 2017 12:16:00 -0000
> @@ -401,7 +401,7 @@ main(int argc, char *argv[])
>       * Set up the prompt.
>       */
>      if (prompt) {
> -     set(STRprompt, Strsave(uid == 0 ? STRsymhash : STRsymcent));
> +     set(STRprompt, Strsave(uid == 0 ? STRpromptroot : STRpromptuser));
>       /* that's a meta-questionmark */
>       set(STRprompt2, Strsave(STRmquestion));
>      }
> @@ -1283,7 +1283,16 @@ printprompt(void)
>       for (cp = value(STRprompt); *cp; cp++)
>           if (*cp == HIST)
>               (void) fprintf(cshout, "%d", eventno + 1);
> -         else {
> +         else if (*cp == '%' && *(cp + 1) == 'm') {
> +             char hostname[HOST_NAME_MAX + 1];
> +             char *p;
> +
> +             gethostname(hostname, sizeof hostname);
> +             if ((p = strchr(hostname, '.')) != NULL)
> +                 *p = '\0';
> +             fprintf(cshout, "%s", hostname);
> +             cp++;
> +         } else {
>               if (*cp == '\\' && cp[1] == HIST)
>                   cp++;
>               (void) vis_fputc(*cp | QUOTE, cshout);
> Index: bin/ksh/lex.c
> ===================================================================
> RCS file: /var/cvs/src/bin/ksh/lex.c,v
> retrieving revision 1.72
> diff -u -p -r1.72 lex.c
> --- bin/ksh/lex.c     7 Dec 2017 01:54:33 -0000       1.72
> +++ bin/ksh/lex.c     8 Dec 2017 11:02:10 -0000
> @@ -1246,7 +1246,8 @@ dopprompt(const char *sp, int ntruncate,
>                       cp++;
>                       if (!*cp)
>                               break;
> -                     if (Flag(FSH))
> +                     /* Expand \h and \$ for both, sh(1) and ksh(1) */
> +                     if (Flag(FSH) && !(*cp == 'h' || *cp == 'p'))
>                               snprintf(strbuf, sizeof strbuf, "\\%c", *cp);
>                       else switch (*cp) {
>                       case 'a':       /* '\' 'a' bell */
> Index: bin/ksh/main.c
> ===================================================================
> RCS file: /var/cvs/src/bin/ksh/main.c,v
> retrieving revision 1.84
> diff -u -p -r1.84 main.c
> --- bin/ksh/main.c    7 Dec 2017 01:54:33 -0000       1.84
> +++ bin/ksh/main.c    8 Dec 2017 10:26:35 -0000
> @@ -316,7 +316,7 @@ main(int argc, char *argv[])
>               /* Set PS1 if it isn't set */
>               if (!(vp->flag & ISSET)) {
>                       /* setstr can't fail here */
> -                     setstr(vp, safe_prompt, KSH_RETURN_ERROR);
> +                     setstr(vp, "\\h\\$ ", KSH_RETURN_ERROR);
>               }
>       }
>  
> 
> 

Reply via email to