1
0

SHLVL blog post

This commit is contained in:
Tim Van Baak 2023-12-18 09:52:26 -08:00
parent 779f96afe1
commit bf7e19ad61
4 changed files with 57 additions and 0 deletions

View File

@ -52,6 +52,11 @@ sup {
:target {
background: palegoldenrod;
}
pre {
background: lightgray;
padding: 5px;
line-height: initial;
}
</style>
</head>
<body>

View File

@ -1,2 +1,3 @@
* [SHLVL PS1](./shlvl.md)
* [Backing up my ZFS NAS to an external drive](./zfs-nas-backup.md)
* [The traditional first software engineer blog post](./blog-start.md)

50
src/blog/2023/shlvl.md Normal file
View File

@ -0,0 +1,50 @@
---
title: SHLVL PS1
pubdate: 2023-12-18T09:53:17-08:00
feed: blog
---
I often find myself in a subshell, usually because of `nix-shell` or `nix develop`, but also sometimes when I run `bash` from `bash` instead of using `pushd` and `popd`. The prompting in Nix shells can be inconsistent betwen tools or versions: `nix-shell` overrides the prompt to `[nix-shell:cwd]$`, but `nix shell`, the `nix` command's replacement for `nix-shell -p`, doesn't change `PS1` at all.
I want a way to tell when I'm in a subshell so I can quit it without quitting my terminal window entirely. There is not, to my knowledge as of writing, an environment variable that distinguishes `nix shell`. However, there is a `bash` feature that helps here: the [`SHLVL`](https://www.gnu.org/software/bash/manual/html_node/Bash-Variables.html#index-SHLVL) environment variable.
> **SHLVL**
> Incremented by one each time a new instance of Bash is started. This is intended to be a count of how deeply your Bash shells are nested.
The default `PS1` on NixOS 23.11 GNOME is this[^1]:
PS1="\n\[\033[1;32m\][\[\e]0;\u@\h: \w\a\]\u@\h:\w]\$\[\033[0m\] "
# |------------|||-----+-----------+||------||\/|---------|
# ANSI color | xterm text to prompt || ANSI color
# code to make | escape set the text || reset
# the prompt | to set title to ||
# green | title |+- $ for user, # for root
# literal [ literal ]
[^1]: [Stack Overflow explanation of xterm title escape](https://unix.stackexchange.com/questions/306716/meaning-of-e0-in-ps1-in-bashrc)
This is what I added to my `.bashrc`. I decomposed it a bit to be more legible to my future self:
_TITLE_BAR="\u@\h: \w"
_SET_TITLE_BAR="\[\e]0;$_TITLE_BAR\a\]"
_PROMPT="\A \u\h:\w"
_SHLVL=$(printf '\$%.0s' $(seq 1 $SHLVL))
_PS1="$_SET_TITLE_BAR[$_PROMPT]$_SHLVL "
export PS1="\[\033[1;32m\]$_PS1\[\033[0m\]"
The `printf` expression here is taken from [this Stack Overflow post](https://stackoverflow.com/questions/5349718/how-can-i-repeat-a-character-in-bash); essentially, it prints the string we want to repeat (`\$`), then formats the input to 0 characters wide. Repeating inputs lets us repeat the format, which `seq` does. Now the prompt shows how many subshells we're in:
[09:04 tvbimperium:~]$ bash
[09:04 tvbimperium:~]$$ bash
[09:04 tvbimperium:~]$$$ bash
[09:04 tvbimperium:~]$$$$ bash
[09:04 tvbimperium:~]$$$$$
exit
[09:05 tvbimperium:~]$$$$
exit
[09:05 tvbimperium:~]$$$
exit
[09:05 tvbimperium:~]$$
exit
[09:05 tvbimperium:~]$

View File

@ -4,5 +4,6 @@ title: Blog
[RSS](./feed.xml)
* [SHLVL PS1](./2023/shlvl.md)
* [Backing up my ZFS NAS to an external drive](./2023/zfs-nas-backup.md)
* [The traditional first software engineer blog post](./2023/blog-start.md)