Quote:
Originally Posted by elbci
aaa... when do I mark this as "solved", now? or 6 months from now when I finally understand and make it work on my computer?
|
I'm never sure how much info to write out when answering questions here. Sometimes I've been snapped on for explaining too much to one of those types of users who say things like "I've used Slackware for over 40 years! don't explain things to me like I'm a newbie!". Usually I'll just leave ideas on what to look up for further reading.
I can give you a bit more context to help you get started though:
There are various shells that you can use on Linux, but the default in Slackware is bash, so I will focus on that.
When you start a terminal (i.e. when you start bash), it runs some scripts to set up the environment. The two general types of shell you use in day-to-day work is either a "login shell" or an "interactive shell". Login shells are when you first login to a console, or when you "su -l", for example, while interactive shells are your typical terminal you open in a graphical environment.
I mention the difference because login shells get their initial environment by running the /etc/profile script, and then your user's ~/.bash_profile script. Interactive shells run the ~/.bashrc script. In any case, these scripts are where you can set your prompt style to use in the terminal when doing it automatically.
Like I said, its the PS1 variable that sets the prompt.
Bash recognizes certain escaped characters to substitute with things like your user name, current directory, machine name, etc. The list from 'man bash' are:
Code:
\a an ASCII bell character (07)
\d the date in "Weekday Month Date" format (e.g., "Tue May
26")
\D{format}
the format is passed to strftime(3) and the result is in‐
serted into the prompt string; an empty format results in
a locale-specific time representation. The braces are
required
\e an ASCII escape character (033)
\h the hostname up to the first `.'
\H the hostname
\j the number of jobs currently managed by the shell
\l the basename of the shell's terminal device name
\n newline
\r carriage return
\s the name of the shell, the basename of $0 (the portion
following the final slash)
\t the current time in 24-hour HH:MM:SS format
\T the current time in 12-hour HH:MM:SS format
\@ the current time in 12-hour am/pm format
\A the current time in 24-hour HH:MM format
\u the username of the current user
\v the version of bash (e.g., 2.00)
\V the release of bash, version + patch level (e.g., 2.00.0)
\w the current working directory, with $HOME abbreviated
with a tilde (uses the value of the PROMPT_DIRTRIM vari‐
able)
\W the basename of the current working directory, with $HOME
abbreviated with a tilde
\! the history number of this command
\# the command number of this command
\$ if the effective UID is 0, a #, otherwise a $
\nnn the character corresponding to the octal number nnn
\\ a backslash
\[ begin a sequence of non-printing characters, which could
be used to embed a terminal control sequence into the
prompt
\] end a sequence of non-printing characters
You will see a number of these characters used in my PS1, or in the default system one on Slackware. That default one for Slackware is set in /etc/profile with the following line:
Which means your prompt is the "user name"@"hostname":"the current directory""$ or #, depending if its a regular user or root".
To add color requires the use of special escaped color codes that the terminal emulator interprets to change the color of text.
Code:
'\033[0m' - Resets the color to default.
'\033[0;30m' - Black
'\033[0;31m' - Red
'\033[0;32m' - Green
'\033[0;33m' - Yellow
'\033[0;34m' - Blue
'\033[0;35m' - Purple
'\033[0;36m' - Cyan
'\033[0;37m' - White
'\033[0;30m' - Bright Black
'\033[0;91m' - Bright Red
'\033[0;92m' - Bright Green
'\033[0;93m' - Bright Yellow
'\033[0;94m' - Bright Blue
'\033[0;95m' - Bright Purple
'\033[0;96m' - Bright Cyan
'\033[0;97m' - Bright White
Also note that the '[0;' part is regular text, and can be written as '[1;' for bold text.
However, bash needs to keep track of how many characters are in the prompt so it knows where the prompt ends and the users typed in text starts. This means that any control characters like color changes need to be wrapped in \[ and \] characters so that bash doesn't count the characters in the color codes. Otherwise bash will mess up your prompt when you do something like type a bunch of characters up to a new line, and then backspace all the way back to start of the prompt. If you don't have proper escaped color codes, the prompt will end up getting messed up.
Lets try a basic example of setting colors in PS1 to use green for the user name, and blue as the hostname. This time I'll use the stock PS1 to start:
Adding color:
Code:
PS1='\[\033[1;92m\]\u\[\033[0m\]@\[\033[1;94m\]\h\[\033[0m\]:\w\$ '
So that sets text "Bright Green", then print the username, then reset the text for the '@' character, then set the text "Bright Blue" for the hostname, then reset after the hostname to print the directory in default color. Note the use of \[ and \] around all non-printing control characters.
To make the prompt different colors for root versus regular users, you need to add some logic to the prompt with an inline if statement. You see this part in my PS1 from the last post (highlighted in red):
Code:
export PS1="\[\033[0;37m\]\342\224\214\342\224\200\$([[ \$? != 0 ]] && echo \"[\[\033[0;31m\]\342\234\227\[\033[0;37m\]]\342\224\200\")[$(if [[ ${EUID} == 0 ]]; then echo ${ROOT_PS1}; else echo ${USER_PS1}; fi)\[\033[0;37m\]]\342\224\200[\[\033[1;95m\]\w\[\033[0;37m\]]\n\[\033[0;37m\]\342\224\224\342\224\200\342\224\200\342\225\274 \[\033[0m\]"
I had taken it further by breaking out the color codes into the $ROOT_PS1 and $USER_PS1 variables to set them in a more user readable way in the lines before that.
There's also logic in my PS1 to print an 'x' when the previous command failed (its the [ \$? != 0 ] bit of logic).
Then there's a bunch of border drawing characters to make the lines on the two line prompt, which are all those octal codes like \342\224\200, etc.
I like the two line prompt because then the current working directory stays on line 1 and can get as big as it needs, while my typed text is always on the next line, with consistent distance from the margin.
Hope that helps get you started on understanding this stuff. Read the "man bash" manual page to get all the details.
Cheers