I installed the tcsh package on Ubuntu 15.10 and the prompt differs depending on how I invoke tcsh.

First off, on Ubuntu 15.10, tcsh and csh really are the same executable:

$ cmp /bin/tcsh /bin/csh && echo 'same' || echo 'different'

$ /bin/tcsh

$ /bin/tcsh -f

Whereas with /bin/csh it ends with a percent sign

$ /bin/csh

$ /bin/csh -f

I haven't set a .cshrc or a .tcshrc file. Is tcsh inspecting the first element of argv to determine what to use as the final character of the prompt?

The /etc/csh.cshrc file does contain logic for changing the prompt if the program is invoked as tcsh, but it is not clear why setting the prompt in this way would change the last character from > to %. This file is also ignored if the -f flag is provided.

# /etc/csh.cshrc: system-wide .cshrc file for csh(1) and tcsh(1)

if ($?tcsh && $?prompt) then

    bindkey "\e[1~" beginning-of-line # Home
    bindkey "\e[7~" beginning-of-line # Home rxvt
    bindkey "\e[2~" overwrite-mode    # Ins
    bindkey "\e[3~" delete-char       # Delete
    bindkey "\e[4~" end-of-line       # End
    bindkey "\e[8~" end-of-line       # End rxvt

    set autoexpand
    set autolist
    set prompt = "%U%m%u:%B%~%b%# "

I don't see it in the manpage, but the source code checks if the program is invoked as tcsh or not. If it is, the code sets the prompt as noted in the question:

HIST = '!';
HISTSUB = '^';
PRCH = tcsh ? '>' : '%';    /* to replace %# in $prompt for normal users */
PRCHROOT = '#';             /* likewise for root */
word_chars = STR_WORD_CHARS;
bslash_quote = 0;           /* PWP: do tcsh-style backslash quoting? */

The program logic is fairly easy to read:

        char *t;

        t = strrchr(argv[0], '/');
            char *s = strrchr(argv[0], '\\');
            if (s)
                t = s;
#endif /* WINNT_NATIVE */
        t = t ? t + 1 : argv[0];
        if (*t == '-') t++;
        progname = strsave((t && *t) ? t : tcshstr);    /* never want a null */
        tcsh = strncmp(progname, tcshstr, sizeof(tcshstr) - 1) == 0;


static const char tcshstr[] = "tcsh";

So it would not pass the test if it were named tcsh10, for instance.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.