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.
> 

hi.

the default prompt works exactly because it doesn;t try to second guess
what the user wants, or what is or isn;t good for them. the mechanism
for changing the prompt is trivial.

i don;t think it makes sense to change the shells in this way.

jmc

> 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