To let bash return "user@hostname:path/to/directory$" as your prompt, add the following line to your ~/.bash_profile:
export PS1='\u@\H:\w$'
or
export PS1='\u@\H:\w$ '
if you like having a space between the $ and the command
to make the changes take effect immediately, run the following command in every open window (or restart Terminal):
source ~/.bash_profile
EDIT:
A list of available strings can be found in the paragraph "PROMPTING" in the man page for bash (man bash
):
PROMPTING
When executing interactively, bash displays the primary prompt PS1 when it is ready to read a command, and the secondary prompt PS2 when it needs more input to complete a command. Bash allows these prompt strings to be customized by
inserting a number of backslash-escaped special characters that are decoded as follows:
\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 inserted 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
\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
Here's a workaround, if you're willing to change your habits a little.
First of all, pick a directory in your PATH that you can write to.
Assuming that you're on your own machine, and you have admin rights,
you could use \Windows
or \Program Files\something
.
But it's probably better
to use something like\Users\username\bin
.
(Add it to your PATH if you don't already have it there.)
Then create a file there called CH.BAT
, or something like that,
with the following contents:
@echo off
REM Pass the argument(s) to the real "cd". If it fails, don't do anything else.
cd %* || exit /b
REM Get our current directory name.
set "dirname=%CD%"
:loop
REM Strip off one directory level -- remove everything through the first \.
set "remove_one=%dirname:*\=%"
REM If there's nothing left, that means dirname ENDS with a \.
REM The only (?) way this can happen is if it is the root directory
REM of a filesystem (partition), e.g., C:\.
REM In this case, set the prompt to the normal thing, C:\>.
if "%remove_one%" == "" goto exit_loop
REM If "%remove_one%" == "%dirname%", that means we are down to
REM the last directory name (i.e., there are no backslashes left).
if "%remove_one%" == "%dirname%" goto exit_loop
set "dirname=%remove_one%"
REM Keep on removing levels until we get to the bottom.
goto loop
:exit_loop
REM To handle the case where a directory name contains dollar sign(s)
REM (e.g., $P$G), replace each $ with $$ to remove its special meaning
REM in the prompt, and just display a $.
set "dirname=%dirname:$=$$%"
prompt %dirname%$G
And then get into the habit of typing ch
instead of cd
(or chdir
, if you're old enough to remember its original name
(which is still supported)).
I believe that the comments explain it fairly well, but, to recapitulate:
- Invoke
cd
on the command-line argument(s).
If it fails, exit the script.
- Use variable substitution
(
%varname:old=new%
)
to strip off directory levels.
Loop until there's nothing left to do.
If the current directory is the root (e.g., C:\
),
then the prompt will be C:\>
(since you didn't specify how to handle that case).
If it is something like C:\top\outer\middle\inner
,
you will get inner>
, as requested.
- As we know, dollar signs are special in the prompt.
But they are legal in directory names.
You can escape dollar signs in the prompt by doubling them;
i.e., if you put
$$
in the prompt, it will display as $
.
So we replace all dollar sign(s) in the directory name
with $$
to get them to display correctly.
- The script hard-codes the current directory name into the prompt string,
so, if you subsequently accidentally type
cd
instead of ch
,
your prompt will not change.
If this happens, just type ch
(or ch .
)
to set the prompt based on the new current directory.
- If you ever want to see the full pathname of your current directory,
type
cd
(or echo %CD%
).
- I have tested this with directory names that contain spaces
(and dollar signs), but I haven't tested every legal character.
Please let me know if you find a problem.
Naturally, it does no good to name the script CD.BAT
or CHDIR.BAT
,
because CMD.EXE always interprets cd
and chdir
as the “change directory” built-in command.
You can run such a script by typing its pathname,
but obviously that’s infeasible (from a workflow perspective)
as an override/replacement for cd
.
Best Answer
Use
realpath
E.g.:
Answered here on stackoverflow: https://stackoverflow.com/a/3915075/441960
Make sure you download the coreutils on Homebrew as it isn't installed by default on all macs:
FYI, my version of MacOS (OSX):