Bash PS1 Generator
bashrcgenerator.com
bashrcgenerator.com
Side by side: >>
Here’s a few the IME on my phone suggested (the middle ones are the same as yours as far as I can tell):
〉> > ≫ 》
function copy_last_command {
history 1 | sed 's/ [0-9]* //' | xclip -i
}
bind -x '"\C-h":copy_last_command'I just copy paste my session, and rerun most commands.
Make your trace output more useful/verbose in your scripts:
set -x
export PS4='+ ${BASH_SOURCE:-}:${FUNCNAME[0]:-}:L${LINENO:-}: '
This will print the filename, function name, line number, and line content during execution. function fish_right_prompt --description 'Write out the right prompt'
set_color 666666
date +'%Y-%m-%d %H:%M:%S'
set_color normal
end
I was sold. I'm never, ever going back to futzing around with a bunch of complex $PSx variables when I can just write a function that does the right thing.Exit status should defo be in the default in all distros.
* As an idea, this is excellent. It's intuitive to use and provides full instructions on how to implement
* Putting an element in any other position than the end of the prompt is fiddly.
* I'd love for the option to to be able to colour elements.
* More advanced or exotic element types such as Git Branch would be excellent (Not sure if Bash supports this, but I've seen it in some shells)
* LiquidPrompt [0] (I'm a former maintainer)
* angel-PS1 [1]: my pet project. Shell prompt code is generated at startup time from Perl code, and uses a Perl angel (not daemon) to get system information.
[1]: https://git-scm.com/book/id/v2/Appendix-A%3A-Git-in-Other-En...
PS1="\$(curl -fsL https://news.ycombinator.com/user?id=USERNAME | awk 'x==1 {print \$1; x=0}; /karma/{x=1};') $PS1"
Replace USERNAME with your HN nick and always have your karma at your fingertips ;-)PS: This is a really bad idea...
[\e[1;33m\u\e[1;32m@\e[1;31m\H \e[1;36m\t\e[0m]
[\e[1;35m\w\e[0m](\e[1;32m\#\e[0m
)\n$
which presents as: [User@HOST 10:21:07][~](2)
$
(Username, hostname, 24 hour local time, CWD, history count, newline, prompt)More detail from my .bashrc:
# Define some colors first:
red='\e[0;31m'
RED='\e[1;31m'
blue='\e[0;34m'
BLUE='\e[1;34m'
cyan='\e[0;36m'
CYAN='\e[1;36m'
green='\e[0;32m'
GREEN='\e[1;32m'
NC='\e[0m' # No Color
yellow='\e[0;33m'
magenta='\e[0;35m'
YELLOW='\e[1;33m'
MAGENTA='\e[1;35m'
export PS1="[${YELLOW}\u${GREEN}@${RED}\H ${CYAN}
\t$NC][${MAGENTA}\w$NC](${GREEN}\#$NC)\n\$ "
I define the colors as it makes it easier to modify PS1 when the spirit moves me.I guess using a generator or toolkit could be useful, but I tweaked mine over the years and prefer it just this way.
Edit: I forgot to mention that I use different colors for user vs. root prompts, as that gives immediate visual confirmation of privilege level.
!! repeats the last command
!N repeats the command with that index in the history
parse_git_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}
PS1="[\u@\h \W\$(parse_git_branch)]\$ "Internally, symbolic-ref resolve the ref in the same way as git branch, just without handling detached HEAD. __git_ps1 use a combination of rev-parse, symbolic-ref and git describe to provide a more interesting output for displaying state of the working directory.
To have the similar output for detached HEAD as git-status (e.g. "HEAD detached at fa0c4e1") then probably `git rev-parse --abbrev-rev` and `git rev-parse --short` should be used together. Unfortunately, while rev-parse can print multiple output in a single command, abbrev-rev and short cannot be used together. In such case, parsing `git status` might indeed be more suitable as it spawn only one executable instead of two.
Some porcelain commands do have --porcelain flag to ensure the stability of the interface, though (e.g. `git status --porcelain=v1`).
if [ "$color_prompt" = yes ]; then
PS1='\[\033[0;32m\]\[\033[0m\033[0;32m\]\u\
[\033[0;36m\] @ \[\033[0;36m\]\h \w\
[\033[0;32m\]$(__git_ps1)\n\[\033[0;32m\]└─\
[\033[0m\033[0;32m\] \$\[\033[0m\033[0;32m\]
AWS:${AWS_PROFILE} ▶\[\033[0m\] '
else
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi git branch --show-current
See https://git-scm.com/docs/git-branchexport PS1="\n\$(kube_ps1)\n\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[0;31m\]\$(__git_ps1)\n\$\[\033[00m\] "
Note it needs the git-prompt.sh script (usually comes with the bash-completion package), and the kube-ps1 script: https://github.com/jonmosco/kube-ps1
It will show you the current kubernetes profile and namespace, user@host, current directory and git branch if you're in a git repo.
function __col1_ps1 {
[[ $MC_SID ]] && return
local termios cur_y
# ask the terminal for any pending (line buffered) input
termios=$(stty --save) && stty -icanon && stty "$termios"
# if there's pending input, assume it's been echoed and we're not in first column
# otherwise ask the terminal for current column and read it from input
if read -t 0 || { IFS='[;' read -s -r -d'R' -p$'\033[6n' _ _ cur_y && [[ $cur_y != 1 ]]; }; then
echo $'\001\033[41m↵\033[m\002\n\001\r\002'
fi
}
PS1='$(__col1_ps1)<the rest of my prompt>'
My full prompt is here: https://github.com/liskin/dotfiles/blob/9785740f7f97d7da1f84...One note: I hate snaps and don't use them personally, but it would make it very easy for you to add HTTPS without changing your existing stack.
set_PS1()
{
local RESET=$(tput sgr0 )
local BOLD=$(tput bold )
local RED=$(tput setaf 1 )
local GREEN=$(tput setaf 2 )
local YELLOW=$(tput setaf 3 )
local BLUE=$(tput setaf 4 )
local MAGENTABG=$(tput setab 5 )
local CYAN=$(tput setaf 6 )
local WHOAMI='\u'
local WHERE='\w'
local HOSTNAME='\h'
local DATE='\D{%Y-%m-%d %H:%M:%S}'
local LAST_RET='${?#0}'
local LINE_1="$YELLOW$DATE $GREEN$WHOAMI$RED@$CYAN$HOSTNAME $BLUE$BOLD$WHERE$RESET"
local LINE_2="\\[$MAGENTABG\\]$LAST_RET\\[$RESET\\]"'\$ '
PS1="$LINE_1\n$LINE_2"
unset -f set_PS1
}
set_PS1
sauce: https://codereview.stackexchange.com/q/174019Apparently the extension PS1 is a reference to PowerShell 1.0.0, thankfully Microsoft did not increase the number.
Source
0 0:00:00
~/Code/company/app$
First number is exit code of previous command, second is how long it took. Credit to https://unix.stackexchange.com/questions/252229/ps1-prompt-t...
for the last part. It's a bit ratchet:- I actually don't care about the exit code unless it was non-zero
- It calculates the delta three times
but I've been to busy to optimise it.
prompt_command() {
_PS1_now=$(printf '%(%s)T')
PS1=$( printf "\n\$? \[\e%02d:%02d:%02d \n\[\033[01;34m\]\w\[\033[00m\]\$ " \
$(( ( _PS1_now - _PS1_lastcmd ) / 3600)) \
$(( (( _PS1_now - _PS1_lastcmd ) % 3600) / 60 )) \
$(( ( _PS1_now - _PS1_lastcmd ) % 60)) \
)
_PS1_lastcmd=$_PS1_now
}
PROMPT_COMMAND='prompt_command'
_PS1_lastcmd=$(printf '%(%s)T') $
A colorful prompt appears, only when 'user or hostname or path' changes, or after certain commands: - username@hostname:pwd
$
Somewhere in .bash_aliases ... ### PROMPT ###
### long prompt (in color) only when 'user or hostname or path' changes, or after certain commands
prompt_command ()
{
local -a a;
local last_cmd;
IFS=' ' read -r -d '' -a a < <( history 1 );
last_cmd="$(printf "%s" "${a[1]}"|xargs -0)";
if [ "$USER_HOSTNAME_PWD" != "$USER@$HOSTNAME:$PWD" ] || [[ " cd src doc ssh sudo su login $(sed -e '/^#.*$/d' -e '/^$/d' -e 's@^.*/@@' /etc/shells|uniq|xargs) " == *" ${last_cmd} "* ]]; then
USER_HOSTNAME_PWD="$USER@$HOSTNAME:$PWD";
echo -e "\\e7\\e(B\\e[m- \\e[3$((($(id -u) != 0) + 1))m${USER}\\e(B\\e[m@\\e[35m${HOSTNAME%%.*}\\e(B\\e[m:\\e[36m${PWD/#$HOME/\~}\\e8";
fi
}
-() { unset USER_HOSTNAME_PWD
}
PROMPT_COMMAND=prompt_command
PS1='$ ';[ "$(id -u)" -eq 0 ] && PS1='# 'Edit: Found it, it’s a cross-shell prompt. Appears to require a binary install.
Then again, I only use 5 of all the plugins available.
~/bin via v1.8.0 via v2.7.16 on (us-east-2) [1]
even on non-project folders and have no idea why that is being listed.
[1] emojis got lost in hn, but it was a coffee cup, a snake and a cloud..
I also have a newline in my prompt which makes it easier to copy commands and output into Jira.
oh-my-zsh does this by default as it comes with the "git" plugin loaded. "gb -vv" is a common thing I run.
tput is a neat command that I wish got used more! I also use `tput cnorm` to ensure the cursor is visible.
You can see what each tput commands are doing by running infocmp. Most TERM implement ANSI-compatible escape codes, but may prefer other escape codes for the same effect (e.g. try comparing `infocmp -1 ansi` and `infocmp -1 xterm` and `infocmp -1 screen`). You can see the entire list of these commands in terminfo(5) (`man 5 terminfo`) in Predefined Capabilities section.
If your terminal ($TERM) is not known to the operating system, you can also import the terminfo definition from another OS in a directory and point the TERMINFO environment variable to it (useful if the legacy OS you connect to via SSH doesn't have full support for your fancy terminal emulator).
It’s more efficient to echo CSI 0m, in shell than to run another process to do the same. Every mainstream terminal supports it.
Save and Restore cursor doesn't always work because I don't necessarily need the vertical position restored, for example:
ls_color () {
tput sc;
/bin/ls --color=auto "$@";
push_cursor_position;
tput rc;
pop_cursor_position
}I built one in 2012 http://xta.github.io/HalloweenBash/ with drag and drop.
I think there is room for someone to create a site to generate PS1 for zsh (since macOS comes with zsh now).
Isn't it correct? I mean, sure, we are talking shell here, so who cares about efficiency, but I don't see the benefit of using export either.
To elaborate, when I say "cluttering," it's not really performance I'm after. Of course I realize that yet another small key value pair in a hashmap matters very little. Rather, I'm thinking in terms of debugging and - worst case - weird side effects.
When I debug something I'm not helped by the environment being filled with unnecessary crap, in much the same way I don't particularly declare a bunch of irrelevant global variables in my programs.
In the worst case, a leaking environment may cause problems. What if another interactive shell process is spawned by a sub shell, and suddenly your prompt that queries your mail server, double checks if there's new stuff in GitHub, fetches the next ten days' weather and renders hamsterdance in your prompt using a hacked font or whatever is inherited (except that now maybe it runs as root). Unlikely? Yeah, sure. Still unnecessary.
In the end though, I suspect many people just aren't aware of the difference between exporting a variable and not, and somehow think that "to declare a variable in a shell you must type export".
Additionally, I have used git-prompt as PROMPT_COMMAND for a long time, and it's certainly the most useful piece of information.
You could even have colors be containers you put other elements inside to make it easier to visualize
I suppose without TLS it could be intercepted and modified to return a malicious bash command, or something, but this random site on the internet could do that on its own without being intercepted anyway.
Who has more incentive to do so: the person that wants their site to have visitors, or a malicious attacker intent on MITM people in the first place?
What a ridiculous defense of insecurity.
I have been using HTTPS Everywhere extension and currently Firefox's HTTPS-Only feature in strict mode for a long time. Nowadays few links fail to work for me, so the failing ones stand out.
:where(:link[href^="http:"])::after {
content: " [http]";
color: red;
text-decoration: none;
}
(I use the :where(…) wrapping so that any site actually trying to use :link::after for real stuff can override my styles without specificity conflicts.)It’s interesting especially to see how often https: sites have http: links to their own domain, which are just going to get redirected back to the https:. (The HN footer has the “Legal” and “Apply to YC” links being to http://www.ycombinator.com/* for no good reason, a very similar case.)
And how horribly many emails use http: tracking links, and how painfully many of those domains don’t speak HTTPS.
HN’s front page normally has 0–2 out of 30 of the links being HTTP, almost always old domains. It’s fairly rare for a new site to go plain HTTP.
A hacked version doesn't have to return a variation of what's on the page already. There's lots of sneaky things you could return, like a malware download pretending to be a Bash PS1 setup script, a fake GitHub based sign-up to harvest login details, a payment form for a fake product, or a simple redirect to another malicious site.
I use NoScript. This page requires me to enable JavaScript for it to work. Because it doesn't use TLS, this allows any miscreant in the middle to injected JS doing god-knows-what into my browser.
If you really insist (in this case IMO understandable) on having me download and run your program, written in a turing complete scripting language, please let me do so in a way where I can be sure it is actually your program (assuming I trust you that far; which for most people I don't, hence NoScript).
--
https://en.wiktionary.org/wiki/insist#Verb
Wiktionary is a website that has improved functionality after turning on JavaScript, but works just fine without it. It does not insist on using JavaScript.
I guess what you actually mean is "no one is insisting on me looking at their website"? That would be true, but I don't recall making any contrary claims.
If I do want to look at a website, the site insists on using JavaScript, but does not use HTTPS, that can be a security issue. That's what my original comment tries to point out.
Those are two completely different attack surfaces. You should be able to trust a single site without having to trust every other hop on the Internet and a good reason why TLS should be used here.
Try this to get the real default:
PS1='[\u@\h \W]\$ 'or
PS!='# '
Now please add some examples, so it's easier to get started with something to modify. :)
$(git branch | grep ^* | colrm 1 2)
You could use $(git branch --show-current)
but if the head is detached it won't show anything ________________
| |," `.| | SgH
| / SONY \ |
|O _\ /> /_ | ___ _
|_(_)'.____.'(_)_| (")__(")
[___|[=]__[=]|___] // \\