Kshrc custom prompt will not work

So Yesterday I switched from Solus Linux to Fedora Linux 30, but I forgot to backup some of my dotfiles including kshrc. I am fairly new to Korn shell and do not know it well, but through memory I was able to at least get this. I did use code from several different source to recreate it. The only problem is that my prompt does not change. When I was on Solus Linux I used the korn shell source from github and now I am using Korn Shell from the copr latest ksh repo for Fedora. If anyone could help me out with my config that would be great.
The way the prompt should look like is: zoomer@fedora:[/u/l/bin]:blush:

## Arrow Key Functions
set -o emacs
alias __A=$(print '\0020') # ^P = up = previous command
alias __B=$(print '\0016') # ^N = down = next command
alias __C=$(print '\0006') # ^F = right = forward a character
alias __D=$(print '\0002') # ^B = left = back a character
alias __H=$(print '\0001') # ^A = home = beginning of line

## Collapsed Directory
_collapsed_pwd() {
  echo $(pwd | perl -pe '
   BEGIN {
      binmode STDIN,  ":encoding(UTF-8)";
      binmode STDOUT, ":encoding(UTF-8)";
   }; s|^$ENV{HOME}|~|g; s|/([^/.])[^/]*(?=/)|/$1|g; s|/\.([^/])[^/]*(?=/)|/.$1|g
')
}

## Reset to normal: \033[0m
NORM="\033[0m"

## Colors:
BLACK="\033[0;30m"
GRAY="\033[1;30m"
RED="\033[0;31m"
LRED="\033[1;31m"
GREEN="\033[0;32m"
LGREEN="\033[1;32m"
YELLOW="\033[0;33m"
LYELLOW="\033[1;33m"
BLUE="\033[0;34m"
LBLUE="\033[1;34m"
PURPLE="\033[0;35m"
PINK="\033[1;35m"
CYAN="\033[0;36m"
LCYAN="\033[1;36m"
LGRAY="\033[0;37m"
WHITE="\033[1;37m"

## Backgrounds
BLACKB="\033[0;40m"
REDB="\033[0;41m"
GREENB="\033[0;42m"
YELLOWB="\033[0;43m"
BLUEB="\033[0;44m"
PURPLEB="\033[0;45m"
CYANB="\033[0;46m"
GREYB="\033[0;47m"

## Attributes:
UNDERLINE="\033[4m"
BOLD="\033[1m"
INVERT="\033[7m"

## Cursor movements
CUR_UP="\033[1A"
CUR_DN="\033[1B"
CUR_LEFT="\033[1D"
CUR_RIGHT="\033[1C"

## Start of display (top left)
SOD="\033[1;1f"

PS1="$(echo "${GREEN}${USER}${NORM}@${HOSTNAME}:[${GREEN}$(_collapsed_pwd)${NORM}:$")"

Try -e on your echo command and escape the $( from _collapsed_pwd like this:

PS1="$(echo -e "${GREEN}${USER}${NORM}@${HOSTNAME}:[${GREEN}\$(_collapsed_pwd)${NORM}]:$")"
1 Like

In ksh93 you can have:

PS1=$(printf "${GREEN}%s${NORM}@%s:${GREEN}%s${NORM}:$ " '$USER' '$HOSTNAME' '$(_collapsed_pwd)')

The ${USER} ${HOSTNAME} and $(_collapsed_pwd) are in 'ticks' for late evaluation.
Most complicated is the late invocation of the function (I had ran some tests: it only works in ksh93 not ksh88).
BTW there is an echo too many, resulting in double evaluation. Should be

_collapsed_pwd() {
  pwd | perl -pe '
   BEGIN {
      binmode STDIN,  ":encoding(UTF-8)";
      binmode STDOUT, ":encoding(UTF-8)";
   }; s|^$ENV{HOME}|~|g; s|/([^/.])[^/]*(?=/)|/$1|g; s|/\.([^/])[^/]*(?=/)|/.$1|g
'
}
1 Like

So I tried what both of you said and it still does not do anything. I looked and I am running KSH 2020.0.0 Stable, which is the latest release. I tried to compile KSH93u and KSH93v from the ast github but both failed due to lack of nmake. Every time I run ksh the prompt is still $.

Does

 . $HOME/.kshrc

work?

Yes it does work. Is there any way I can make it run on startup of ksh?

Hmm, I suggest to consult the man page.

man ksh

And /search for ENV
What does it say?

The Man page says:

ENV    If this variable is set, then parameter expansion, command substitution, and arithmetic substitution are performed on the value to generate the pathname of the script that will be exe�
                     cuted  when  the shell is invoked interactively (see Invocation below).  This file is typically used for alias and function definitions.  The default value is $HOME/.kshrc.  On systems
                     that support a system wide  /etc/ksh.kshrc initialization file, if the filename generated by the expansion of ENV begins with /./ or ././ the system wide initialization file  will  not
                     be executed.

When I run echo $ENV It outputs /usr/share/Modules/init/profile.sh which says:

# get current shell name by querying shell variables or looking at parent
# process name
if [ -n "${BASH:-}" ]; then
   shell=${BASH##*/}
elif [ -n "${ZSH_NAME:-}" ]; then
   shell=$ZSH_NAME
else
   shell=$(/usr/bin/basename $(/usr/bin/ps -p $$ -ocomm=))
fi

if [ -f /usr/share/Modules/init/$shell ]; then
   . /usr/share/Modules/init/$shell
else
   . /usr/share/Modules/init/sh
fi

I'm not that familiar with the environment-modules package (never run it myself), but I would have expected that /usr/share/Modules/init/ksh should end up sourcing $HOME/.kshrc if you have one.

So I added

. $HOME/.kshrc;

to the bottom of the file and it fixed it. Thank you all for helping me with this error.

Can I recommend [ -f "$HOME"/.kshrc ] && . "$HOME"/.kshrc to avoid the

ksh: .: /home/testuser/.kshrc: cannot open [No such file or directory]

error when ksh is executed by a user without a $HOME/.kshrc file

There must be a bug in that version of environment-modules.
Are there any results of

grep -w ENV /etc/profiles.d/modules*

where ENV is assigned the /usr/share/Modules/init/ ?
Then this mistake should be commented out/disabled.
(And the generally not good previous workaround can be backed out.)

I agree that something is not quite right with the environment-modules package in the OP system.

I believe removing that assignment of ENV will stop environment-modules working at all
and may have a more negative impact on the system as a whole than the workaround currently used.

Depending on criticality of the system. I would consider reinstalling the environment-modules package, or if it's features are not required. removing it.

So, I just update from Fedora 30 to Fedora 31, and this seems to have fixed the problem because echo $ENV now outputs /home/zoomer/.kshrc. I believe that this was a bug for Fedora 30. Thank you to everyone that help me get the temporary fix.

1 Like