I have finally come up with a favourite PS1 format but I find it takes too long to load.

The part that is slowing it down is when I call the external commands in the prompt. I simply want to show the # of entries and # of hidden files of the directory.

I followed these 2 pages as a guide to make the prompt: "External command in prompt" and "customizing bash command prompt blog". I could not get Daniel's "customizing bash command prompt blog" method to work any faster than what I came up with. Why would he use "pwd" instead of \w anyway? Plus I don't get why he made a var and echoed it ($OUT). Oh well, here's what I did...

I sort of combined both methods and came up with the below, which works, but not as fast as I would like...

export PS1="\[\e[2;37m\]\d \[\e[2;37m\] @ \[\e[2;37m\] \t \[\e[2;33m\]> Currently in: \[\e[0;33m\]\w [\$(ls -A | wc -l) entries and \$[\$(ls -A | wc -l) - \$(ls | wc -l)$wc -l)] are hidden] \[\e[0m\]
\[\e[2;36m\]\u\[\e[0;37m\]@\[\e[1;32m\]\h\[\e[0;33m\] \$ \[\e[0m\]"

Newly edited command in bashrc, as per @mikeserv's suggestions:

export PS1="\[\e[2;37m\]\d \[\e[2;37m\] @ \[\e[2;37m\] \t \[\e[2;33m\]>Currently in: \[\e[0;33m\] $(($(count_glob c * count_glob h .*)0)) entries and $h are hidden \[\e[0m\]
\[\e[3;36m\]\u\[\e[0;37m\]@\[\e[1;93m\]\h\[\e[0;33m\] \$\[\e[0m\]"

The results of which are below:

Tue Jan 20  @  18:37:58 >Currently in:  24 entries and  are hidden
  • you've gotta use single quotes when you define the $PS1.
    – mikeserv
    Jan 21 '15 at 3:19
count_glob() { 
     [ -e "$1" ]
     echo "($v=$((!$?*$#)))+"

You could declare a function like the above. Then instead of ls and the rest you could just do...

...Currently in: $(($(
    v=c count_glob *
    v=h count_glob .*
)-2)) entries and $((h-2)) are hidden...

I only removed the escape sequences because they're not relevant here - it will work as well with them.

So all together now...

export PS1='\[\e[2;37m\]\d \[\e[2;37m\] @ \[\e[2;37m\] \t \[\e[2;33m\]>'\
'Currently in: \[\e[0;33m\] $(($(
    v=c count_glob * 
    v=h count_glob .*
)-2)) entries and $((h-2)) are hidden '\
'\[\e[3;36m\]\u\[\e[0;37m\]@\[\e[1;93m\]\h\[\e[0;33m\] \$\[\e[0m\]'

Ok, so what's going on here is the count_glob function is provided an argument list of all of the (hidden or not) files in the current directory. The special parameter $# represents the total count of a shell's positional parameters - its arguments - and every shell function gets its own set of those.

[ -e "$1" ]

... is a check to verify the first argument actually exists - which is actually not necessary in the .* case because there are always two . and .. files to resolve - but for * there is a chance that - if the directory is empty - the glob will not resolve and * will still get passed as argument. So in the function the check is done and the boolean not of the test's return is multiplied by the argument count. This works because if the test is true it returns 0 and if false other than zero - so multiplying by the inverse of those figures works out to get your count right.

The last factor to consider here is the way the shell handles arithmetic. In most cases you cannot just pass a variable definition out of a subshell in this way so easily - but with an arithmetic eval you can - because it really is an eval in the truest sense. The two calls to count_glob wind up printing a statement that looks like:


...and the shell honors and assigns those figures - even for subsequent calls. You can test this at your prompt - do echo "$h" "$c" and you'll get the same values as your prompt reports every time. I suppose that might be useful for other things.

  • What does your function do? It surely does not provide a counting of the files, does it? I get the following, as in how to call the function, but the function itself does not jive, man. Jan 20 '15 at 9:29
  • The function itself sets fine, but when I call it I get an error. That is from the command line. If I put your code in the bashrc file and run it. I get a count (though wrong), and it does not update with each cd into a different directory. I've updated question above. Thanks for the help. Jan 21 '15 at 2:38
  • I believe ya, but am just calling it as I see it. Perhaps it's worth mentioning I am running Cygwin? I have updated my exact PS1 command so that any mistakes can be seen. Jan 21 '15 at 2:47
  • v=c count_glob * (c=4)+ Jan 21 '15 at 2:55
  • and (h=18)+ ... Yes, 4 directories and 18 hidden files (though 2 of those are . and ..) Jan 21 '15 at 2:57

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.