Sat, 9 Dec 2017 18:44:44 +0100 Theo Buehler <[email protected]>
> 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.
Hi,
I feel the need for this, and have always customised my PS1 everywhere.
Please, also test this to make sure Emacs tramp mode does not get to be
a show stopper, for it expects the prompt to be a certain simple form..
Maybe POSIX / something else, I'd be really really disappointed if they
refused to adjust around (any) non-standard implementations on our end.
Kind regards,
Anton Lazarov
> In single user mode and the early installer, gethostname() returns the
> empty string, so the familiar prompts will be displayed there.
>
> 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);
> }
> }
>
>