From bf7e19ad61f36f7e83fe8e5cc4805e341e60fcb8 Mon Sep 17 00:00:00 2001 From: Tim Van Baak Date: Mon, 18 Dec 2023 09:52:26 -0800 Subject: [PATCH] SHLVL blog post --- src/.template.html | 5 +++++ src/blog/2023/index.md | 1 + src/blog/2023/shlvl.md | 50 ++++++++++++++++++++++++++++++++++++++++++ src/blog/index.md | 1 + 4 files changed, 57 insertions(+) create mode 100644 src/blog/2023/shlvl.md diff --git a/src/.template.html b/src/.template.html index 0bcddb9..9249cd7 100644 --- a/src/.template.html +++ b/src/.template.html @@ -52,6 +52,11 @@ sup { :target { background: palegoldenrod; } +pre { + background: lightgray; + padding: 5px; + line-height: initial; +} diff --git a/src/blog/2023/index.md b/src/blog/2023/index.md index b4298e2..d0fa04c 100644 --- a/src/blog/2023/index.md +++ b/src/blog/2023/index.md @@ -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) \ No newline at end of file diff --git a/src/blog/2023/shlvl.md b/src/blog/2023/shlvl.md new file mode 100644 index 0000000..ec2f534 --- /dev/null +++ b/src/blog/2023/shlvl.md @@ -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:~]$ diff --git a/src/blog/index.md b/src/blog/index.md index 28c48e4..07790f4 100644 --- a/src/blog/index.md +++ b/src/blog/index.md @@ -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) \ No newline at end of file