Skip to content

Commit 3888140

Browse files
authored
feat(snippets): killport (#377)
* feat(snippets): killport * feat(snippets): better recordings * fix(build): use correct ubuntu version * fix(build): ubuntu version for actions
1 parent d026ede commit 3888140

File tree

12 files changed

+373
-4
lines changed

12 files changed

+373
-4
lines changed

.github/workflows/pull-request.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ on: [pull_request]
55

66
jobs:
77
validate-pull-request:
8-
runs-on: ubuntu-20.04
8+
runs-on: ubuntu-24.04
99
steps:
1010
- name: Checkout
1111
uses: actions/checkout@v4
@@ -33,7 +33,7 @@ jobs:
3333
# See:
3434
# https://github.com/marketplace/actions/deploy-pr-preview
3535
deploy-preview:
36-
runs-on: ubuntu-20.04
36+
runs-on: ubuntu-24.04
3737
steps:
3838
- name: Checkout
3939
uses: actions/checkout@v4

.github/workflows/release-please.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ on:
99
- main
1010
jobs:
1111
release-please:
12-
runs-on: ubuntu-20.04
12+
runs-on: ubuntu-24.04
1313
steps:
1414
- uses: google-github-actions/release-please-action@v3
1515
id: release

docs/07-shell-snippets/00-index.md

Lines changed: 114 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: 'Shell Snippets'
33
slug: '/shell-snippets/'
44
---
55

6-
After finishing the [Effective Shell Book](https://amzn.to/4ho0F91) I still find myself regularly discovering techniques that are huge time-savers. I've called these **Effective Shell Snippets** and will update this page with them from time to time, so check back regularly!
6+
After finishing the [Effective Shell Book](https://amzn.to/4ho0F91) I still find myself regularly discovering or remembering techniques that are huge time-savers. I've called these **Effective Shell Snippets** and will update this page with them from time to time, so check back regularly!
77

88
### Git + AI: Interactively Staging Changes, Summarising with AI
99

@@ -112,3 +112,116 @@ example: # Here's an example of how to add a description!
112112
```
113113

114114
This is also documented in a little repo at [github.com/dwmkerr/makefile-help](https://github.com/dwmkerr/makefile-help).
115+
116+
### Dot files and `envsubst`
117+
118+
The `envsubst` command can be used to quickly create and populate template files. When combined with `.env` files, which are a common feature of projects that need to manage secrets, you can rapidly inject secrets or configuration into workflows. Here's a quick demo - which is detailed below:
119+
120+
![Envsubst Demo](./snippets/envsubst/envsubst.svg)
121+
122+
In this demo we:
123+
124+
- Show the contents of a `.env` file. This is shown in colour by using `bat` - a popular alternative to `cat`.
125+
- Show the contents of a `secret.template.yaml` file - which has placeholders for sensitive confiratu
126+
127+
```bash
128+
# First create a template.
129+
cat <<EOF > secret.template.yaml
130+
apiVersion: v1
131+
kind: Secret
132+
metadata:
133+
name: my-secret
134+
type: Opaque
135+
data:
136+
username: \${USERNAME}
137+
password: \${PASSWORD}
138+
EOF
139+
140+
# Demo is better in colors. This is the template above but from bat.
141+
alias cat="bat --plain --theme base16 --force-colorization --language yaml" && clear
142+
143+
# Let's check how this looks.
144+
cat secret.template.yaml
145+
146+
# Now demo substitute env vars. Pipe into cat for colors.
147+
USERNAME=developer PASSWORD=123 envsubst < config.template.yaml | cat
148+
149+
# Demo:
150+
151+
# Setup
152+
source ./init.sh
153+
154+
# Show secret.
155+
bat secret.template.yaml
156+
157+
# Show env.
158+
bat .env
159+
160+
# Show subsitution.
161+
source .env
162+
envsubst < secret.template.yaml
163+
164+
# Show more.
165+
PASSWORD=123 envsubst < secret.template.yaml
166+
```
167+
168+
### Free up a port
169+
170+
It's really easy to leave applications that are listening to a port, such as application servers or docker containers running by mistake. In this circumstance you can find the process that is using the port, grab its process ID and then kill it. But beyond the fact that `lsof` needs to be used, I always forget the command.
171+
172+
The `killport` function finds the process using the port, kills it, and shows a quick summary:
173+
174+
```
175+
$ killport 3000
176+
killed process with id 48022 using port 3000: next-server (v15.3.3)
177+
```
178+
179+
![Demo](./snippets/killport/recording.cast)
180+
181+
In this case I use the `killport` function defined below:
182+
183+
```bash
184+
killport() {
185+
local name="killport"
186+
if [[ "$1" == "-h" ]]; then
187+
echo "usage: ${name} <port>"
188+
echo " Kills the process using the specified port, e.g:"
189+
echo " ${name} 8080"
190+
return 0
191+
fi
192+
193+
# Check if port number was provided
194+
if [[ -z "$1" ]]; then
195+
echo "error: no port specified"
196+
echo "usage: ${name} <port>"
197+
return 1
198+
fi
199+
200+
local port="$1"
201+
202+
# Find the process using the port
203+
local pid=$(lsof -ti :"${port}")
204+
205+
if [[ -z "$pid" ]]; then
206+
echo "no process found using port ${port}"
207+
return 1
208+
fi
209+
210+
# Get process info before killing it
211+
local process_info=$(ps -p "${pid}" -o comm | tail -n 1)
212+
213+
# Kill the process, update the user.
214+
if kill "${pid}"; then
215+
echo -e "killed process using port \e[1;37m${port}\e[0m: \e[1;32m${process_info}\e[0m"
216+
else
217+
echo "failed to kill process ${pid} using port ${port}"
218+
return 1
219+
fi
220+
}
221+
```
222+
223+
Lots of fun tweaks could be made to this function, such as:
224+
225+
- Asking for operator to confirm before killing the process
226+
- Listing all processes using a port range, or all ports
227+
- Allowing the user for force kill if a regular kill doesn't free up the port
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export USERNAME=admin
2+
export PASSWORD=p@ssw0rd
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
{"version": 2, "width": 80, "height": 15, "timestamp": 1744108943, "env": {"SHELL": "/usr/local/bin/bash", "TERM": "xterm-256color"}, "title": "Terminal AI"}
2+
[1.414229, "o", "\u001b[?2004h\r\n\u001b[1m\u001b[34m07-shell-snippets/snippets/envsubst\u001b(B\u001b[m \u001b[32m\u001b[4mmain\u001b(B\u001b[m \u001b[31m!\u001b(B\u001b[m \u001b[35mconda/\u001b[1mbase\u001b[0m\u001b(B\u001b[m \r\n\u001b[1m\u001b[37m$\u001b(B\u001b[m "]
3+
[1.974044, "o", "\u001b[7msource ./init.sh\u001b[27m\r\n\r"]
4+
[2.43966, "o", "\u001b[A\u001b[C\u001b[Csource ./init.sh\r\n"]
5+
[2.440432, "o", "\r\u001b[A\r\n\u001b[?2004l\r"]
6+
[2.449554, "o", "\u001b[H\u001b[2J\u001b[3J"]
7+
[2.608423, "o", "\u001b[?2004h\r\n\u001b[1m\u001b[34m07-shell-snippets/snippets/envsubst\u001b(B\u001b[m \u001b[32m\u001b[4mmain\u001b(B\u001b[m \u001b[31m!\u001b(B\u001b[m \u001b[35mconda/\u001b[1mbase\u001b[0m\u001b(B\u001b[m \r\n\u001b[1m\u001b[37m$\u001b(B\u001b[m "]
8+
[3.311795, "o", "b"]
9+
[3.429073, "o", "a"]
10+
[3.574034, "o", "t"]
11+
[4.092826, "o", " "]
12+
[4.257853, "o", "."]
13+
[4.366046, "o", "e"]
14+
[4.498265, "o", "n"]
15+
[4.656332, "o", "v"]
16+
[4.852409, "o", "\r\n"]
17+
[4.852573, "o", "\u001b[?2004l\r"]
18+
[4.881763, "o", "\r\u001b[35mexport\u001b[0m\u001b[37m \u001b[0m\u001b[37mUSERNAME\u001b[0m\u001b[37m=\u001b[0m\u001b[37madmin\u001b[0m\u001b[m\r\n\u001b[35mexport\u001b[0m\u001b[37m \u001b[0m\u001b[37mPASSWORD\u001b[0m\u001b[37m=\u001b[0m\u001b[37mp@ssw0rd\u001b[0m\u001b[m\r\n\r\u001b[K"]
19+
[4.961946, "o", "\u001b[?2004h\r\n\u001b[1m\u001b[34m07-shell-snippets/snippets/envsubst\u001b(B\u001b[m \u001b[32m\u001b[4mmain\u001b(B\u001b[m \u001b[31m!\u001b(B\u001b[m \u001b[35mconda/\u001b[1mbase\u001b[0m\u001b(B\u001b[m \r\n\u001b[1m\u001b[37m$\u001b(B\u001b[m "]
20+
[6.189847, "o", "b"]
21+
[6.326162, "o", "a"]
22+
[6.433507, "o", "t"]
23+
[6.532772, "o", " "]
24+
[6.923665, "o", "s"]
25+
[7.008378, "o", "e"]
26+
[7.186081, "o", "cret.template.yaml "]
27+
[7.684088, "o", "\r\n\u001b[?2004l\r"]
28+
[7.743424, "o", "\r\u001b[31mapiVersion\u001b[0m\u001b[37m:\u001b[0m\u001b[37m \u001b[0m\u001b[32mv1\u001b[0m\u001b[m\r\n\u001b[31mkind\u001b[0m\u001b[37m:\u001b[0m\u001b[37m \u001b[0m\u001b[32mSecret\u001b[0m\u001b[m\r\n\u001b[31mmetadata\u001b[0m\u001b[37m:\u001b[0m\u001b[m\r\n\u001b[37m \u001b[0m\u001b[31mname\u001b[0m\u001b[37m:\u001b[0m\u001b[37m \u001b[0m\u001b[32mmy-secret\u001b[0m\u001b[m\r\n\u001b[31mtype\u001b[0m\u001b[37m:\u001b[0m\u001b[37m \u001b[0m\u001b[32mOpaque\u001b[0m\u001b[m\r\n\u001b[31mdata\u001b[0m\u001b[37m:\u001b[0m\u001b[m\r\n\u001b[37m \u001b[0m\u001b[31musername\u001b[0m\u001b[37m:\u001b[0m\u001b[37m \u001b[0m\u001b[32m${USERNAME}\u001b[0m\u001b[m\r\n\u001b[37m \u001b[0m\u001b[31mpassword\u001b[0m\u001b[37m:\u001b[0m\u001b[37m \u001b[0m\u001b[32m${PASSWORD}\u001b[0m\u001b[m\r\n\r\u001b[K"]
29+
[7.825067, "o", "\u001b[?2004h\r\n\u001b[1m\u001b[34m07-shell-snippets/snippets/envsubst\u001b(B\u001b[m \u001b[32m\u001b[4mmain\u001b(B\u001b[m \u001b[31m!\u001b(B\u001b[m \u001b[35mconda/\u001b[1mbase\u001b[0m\u001b(B\u001b[m \r\n\u001b[1m\u001b[37m$\u001b(B\u001b[m "]
30+
[9.244929, "o", "s"]
31+
[9.337423, "o", "o"]
32+
[9.410046, "o", "u"]
33+
[9.517257, "o", "r"]
34+
[9.713587, "o", "c"]
35+
[9.768928, "o", "e"]
36+
[9.811702, "o", " "]
37+
[9.974041, "o", "."]
38+
[10.108996, "o", "e"]
39+
[10.231267, "o", "n"]
40+
[10.348152, "o", "v"]
41+
[10.816038, "o", "\r\n"]
42+
[10.816108, "o", "\u001b[?2004l\r"]
43+
[10.922994, "o", "\u001b[?2004h\r\n\u001b[1m\u001b[34m07-shell-snippets/snippets/envsubst\u001b(B\u001b[m \u001b[32m\u001b[4mmain\u001b(B\u001b[m \u001b[31m!\u001b(B\u001b[m \u001b[35mconda/\u001b[1mbase\u001b[0m\u001b(B\u001b[m \r\n\u001b[1m\u001b[37m$\u001b(B\u001b[m "]
44+
[11.452655, "o", "e"]
45+
[11.58162, "o", "n"]
46+
[11.728454, "o", "v"]
47+
[12.100739, "o", "s"]
48+
[12.246567, "o", "u"]
49+
[12.378394, "o", "b"]
50+
[12.710763, "o", "st "]
51+
[13.274213, "o", "<"]
52+
[13.406007, "o", " "]
53+
[14.509403, "o", "s"]
54+
[14.617278, "o", "e"]
55+
[14.831949, "o", "cret.template.yaml "]
56+
[15.37469, "o", "\r\n"]
57+
[15.374761, "o", "\u001b[?2004l\r"]
58+
[15.388983, "o", "apiVersion: v1\r\nkind: Secret\r\nmetadata:\r\n name: my-secret\r\ntype: Opaque\r\ndata:\r\n username: admin\r\n password: p@ssw0rd\r\n"]
59+
[15.49281, "o", "\u001b[?2004h\r\n\u001b[1m\u001b[34m07-shell-snippets/snippets/envsubst\u001b(B\u001b[m \u001b[32m\u001b[4mmain\u001b(B\u001b[m \u001b[31m!\u001b(B\u001b[m \u001b[35mconda/\u001b[1mbase\u001b[0m\u001b(B\u001b[m \r\n\u001b[1m\u001b[37m$\u001b(B\u001b[m "]
60+
[16.147926, "o", "envsubst < secret.template.yaml "]
61+
[16.471567, "o", " "]
62+
[17.130184, "o", "\b\u001b[K"]
63+
[17.351013, "o", "|"]
64+
[17.738301, "o", " "]
65+
[18.340157, "o", "c"]
66+
[18.483199, "o", "a"]
67+
[18.551749, "o", "t"]
68+
[18.672216, "o", "\r\n"]
69+
[18.672437, "o", "\u001b[?2004l\r"]
70+
[18.686152, "o", "\u001b[31mapiVersion\u001b[0m\u001b[37m:\u001b[0m\u001b[37m \u001b[0m\u001b[32mv1\u001b[0m\r\n\u001b[31mkind\u001b[0m\u001b[37m:\u001b[0m\u001b[37m \u001b[0m\u001b[32mSecret\u001b[0m\r\n"]
71+
[18.686295, "o", "\u001b[31mmetadata\u001b[0m\u001b[37m:\u001b[0m\r\n\u001b[37m \u001b[0m\u001b[31mname\u001b[0m\u001b[37m:\u001b[0m\u001b[37m \u001b[0m\u001b[32mmy-secret\u001b[0m\r\n\u001b[31mtype\u001b[0m\u001b[37m:\u001b[0m\u001b[37m \u001b[0m\u001b[32mOpaque\u001b[0m\r\n\u001b[31mdata\u001b[0m\u001b[37m:\u001b[0m\r\n\u001b[37m \u001b[0m\u001b[31musername\u001b[0m\u001b[37m:\u001b[0m\u001b[37m \u001b[0m\u001b[32madmin\u001b[0m\r\n"]
72+
[18.686404, "o", "\u001b[37m \u001b[0m\u001b[31mpassword\u001b[0m\u001b[37m:\u001b[0m\u001b[37m \u001b[0m\u001b[32mp@ssw0rd\u001b[0m\r\n"]
73+
[18.787559, "o", "\u001b[?2004h\r\n\u001b[1m\u001b[34m07-shell-snippets/snippets/envsubst\u001b(B\u001b[m \u001b[32m\u001b[4mmain\u001b(B\u001b[m \u001b[31m!\u001b(B\u001b[m \u001b[35mconda/\u001b[1mbase\u001b[0m\u001b(B\u001b[m \r\n\u001b[1m\u001b[37m$\u001b(B\u001b[m "]
74+
[19.917495, "o", "envsubst < secret.template.yaml | cat"]
75+
[20.705711, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"]
76+
[21.205883, "o", "\u001b[1@P"]
77+
[21.46006, "o", "\u001b[1@S"]
78+
[21.968549, "o", "\b\u001b[1P"]
79+
[22.047141, "o", "\u001b[1@A"]
80+
[22.084128, "o", "\u001b[1@S"]
81+
[22.283118, "o", "\u001b[1@S"]
82+
[22.584601, "o", "\u001b[1@W"]
83+
[22.685737, "o", "\u001b[1@O"]
84+
[22.80897, "o", "\u001b[1@R"]
85+
[22.868806, "o", "\u001b[1@D"]
86+
[23.143683, "o", "\u001b[1@="]
87+
[23.397864, "o", "\u001b[1@1"]
88+
[23.451889, "o", "\u001b[1@2"]
89+
[23.522645, "o", "\u001b[1@3"]
90+
[23.610962, "o", "\u001b[1@ "]
91+
[23.905234, "o", "\r\n\u001b[?2004l\r"]
92+
[23.924711, "o", "\u001b[31mapiVersion\u001b[0m\u001b[37m:\u001b[0m\u001b[37m \u001b[0m\u001b[32mv1\u001b[0m\r\n\u001b[31mkind\u001b[0m\u001b[37m:\u001b[0m\u001b[37m \u001b[0m\u001b[32mSecret\u001b[0m\r\n"]
93+
[23.924926, "o", "\u001b[31mmetadata\u001b[0m\u001b[37m:\u001b[0m\r\n\u001b[37m \u001b[0m\u001b[31mname\u001b[0m\u001b[37m:\u001b[0m\u001b[37m \u001b[0m\u001b[32mmy-secret\u001b[0m\r\n\u001b[31mtype\u001b[0m\u001b[37m:\u001b[0m\u001b[37m \u001b[0m\u001b[32mOpaque\u001b[0m\r\n\u001b[31mdata\u001b[0m\u001b[37m:\u001b[0m\r\n\u001b[37m \u001b[0m\u001b[31musername\u001b[0m\u001b[37m:\u001b[0m\u001b[37m \u001b[0m\u001b[32madmin\u001b[0m\r\n"]
94+
[23.925043, "o", "\u001b[37m \u001b[0m\u001b[31mpassword\u001b[0m\u001b[37m:\u001b[0m\u001b[37m \u001b[0m\u001b[38;5;9m123\u001b[0m\r\n"]
95+
[24.025895, "o", "\u001b[?2004h\r\n\u001b[1m\u001b[34m07-shell-snippets/snippets/envsubst\u001b(B\u001b[m \u001b[32m\u001b[4mmain\u001b(B\u001b[m \u001b[31m!\u001b(B\u001b[m \u001b[35mconda/\u001b[1mbase\u001b[0m\u001b(B\u001b[m \r\n\u001b[1m\u001b[37m$\u001b(B\u001b[m "]
96+
[24.680035, "o", "PASSWORD=123 envsubst < secret.template.yaml | cat"]
97+
[24.972703, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"]
98+
[25.75738, "o", "\u001b[1@U"]
99+
[25.84755, "o", "\u001b[1@S"]
100+
[25.954557, "o", "\u001b[1@E"]
101+
[26.015216, "o", "\u001b[1@R"]
102+
[26.095096, "o", "\u001b[1@N"]
103+
[26.19492, "o", "\u001b[1@A"]
104+
[26.283728, "o", "\u001b[1@M"]
105+
[26.372268, "o", "\u001b[1@E"]
106+
[26.594335, "o", "\u001b[1@-"]
107+
[27.073742, "o", "\b\u001b[1P"]
108+
[27.176135, "o", "\u001b[1@="]
109+
[27.299944, "o", "\u001b[1@d"]
110+
[27.373786, "o", "\u001b[1@w"]
111+
[27.470683, "o", "\u001b[1@m"]
112+
[27.539954, "o", "\u001b[1@k"]
113+
[27.590762, "o", "\u001b[1@e"]
114+
[27.674153, "o", "\u001b[1@r"]
115+
[27.807951, "o", "\u001b[1@r"]
116+
[27.895631, "o", "\u001b[1@ "]
117+
[28.132529, "o", "\r\n"]
118+
[28.132748, "o", "\u001b[?2004l\r"]
119+
[28.15009, "o", "\u001b[31mapiVersion\u001b[0m\u001b[37m:\u001b[0m\u001b[37m \u001b[0m\u001b[32mv1\u001b[0m\r\n\u001b[31mkind\u001b[0m\u001b[37m:\u001b[0m\u001b[37m \u001b[0m\u001b[32mSecret\u001b[0m\r\n"]
120+
[28.15028, "o", "\u001b[31mmetadata\u001b[0m\u001b[37m:\u001b[0m\r\n\u001b[37m \u001b[0m\u001b[31mname\u001b[0m\u001b[37m:\u001b[0m\u001b[37m \u001b[0m\u001b[32mmy-secret\u001b[0m\r\n\u001b[31mtype\u001b[0m\u001b[37m:\u001b[0m\u001b[37m \u001b[0m\u001b[32mOpaque\u001b[0m\r\n\u001b[31mdata\u001b[0m\u001b[37m:\u001b[0m\r\n\u001b[37m \u001b[0m\u001b[31musername\u001b[0m\u001b[37m:\u001b[0m\u001b[37m \u001b[0m\u001b[32mdwmkerr\u001b[0m\r\n\u001b[37m \u001b[0m\u001b[31mpassword\u001b[0m\u001b[37m:\u001b[0m\u001b[37m \u001b[0m\u001b[38;5;9m123\u001b[0m\r\n"]
121+
[28.265069, "o", "\u001b[?2004h\r\n\u001b[1m\u001b[34m07-shell-snippets/snippets/envsubst\u001b(B\u001b[m \u001b[32m\u001b[4mmain\u001b(B\u001b[m \u001b[31m!\u001b(B\u001b[m \u001b[35mconda/\u001b[1mbase\u001b[0m\u001b(B\u001b[m \r\n\u001b[1m\u001b[37m$\u001b(B\u001b[m "]
122+
[29.836427, "o", "e"]
123+
[29.905896, "o", "c"]
124+
[29.981684, "o", "h"]
125+
[30.038105, "o", "o"]
126+
[30.19245, "o", " "]
127+
[30.390608, "o", "\""]
128+
[30.617878, "o", "c"]
129+
[30.718311, "o", "o"]
130+
[30.831755, "o", "o"]
131+
[30.978371, "o", "l"]
132+
[31.257071, "o", "\""]
133+
[31.471589, "o", "\r\n"]
134+
[31.4717, "o", "\u001b[?2004l\r"]
135+
[31.472563, "o", "cool\r\n"]
136+
[31.589395, "o", "\u001b[?2004h\r\n\u001b[1m\u001b[34m07-shell-snippets/snippets/envsubst\u001b(B\u001b[m \u001b[32m\u001b[4mmain\u001b(B\u001b[m \u001b[31m!\u001b(B\u001b[m \u001b[35mconda/\u001b[1mbase\u001b[0m\u001b(B\u001b[m \r\n\u001b[1m\u001b[37m$\u001b(B\u001b[m "]
137+
[32.46266, "o", "\u001b[?2004l\r\r\n"]
138+
[32.463063, "o", "exit\r\n"]
353 KB
Loading
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# First create a template.
2+
cat <<EOF > secret.template.yaml
3+
apiVersion: v1
4+
kind: Secret
5+
metadata:
6+
name: my-secret
7+
type: Opaque
8+
data:
9+
username: \${USERNAME}
10+
password: \${PASSWORD}
11+
EOF
12+
13+
# Demo is better in colors. This is the template above but from bat.
14+
alias cat="bat --plain --theme base16 --force-colorization --language yaml" && clear
15+
16+
# Let's check how this looks.
17+
cat secret.template.yaml
18+
19+
# Now demo substitute env vars. Pipe into cat for colors.
20+
USERNAME=developer PASSWORD=123 envsubst < config.template.yaml | cat
21+
22+
# Demo:
23+
24+
# Setup
25+
source ./init.sh
26+
27+
# Show secret.
28+
bat secret.template.yaml
29+
30+
# Show env.
31+
bat .env
32+
33+
# Show subsitution.
34+
source .env
35+
envsubst < secret.template.yaml
36+
37+
# Show more.
38+
PASSWORD=123 envsubst < secret.template.yaml

docs/07-shell-snippets/snippets/envsubst/envsubst.svg

Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Demo is better in colors. This is the template above but from bat.
2+
alias cat="bat --plain --theme base16 --force-colorization --language yaml"
3+
alias bat="bat --plain --theme base16 --force-colorization"
4+
clear
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{"version": 2, "width": 80, "height": 15, "timestamp": 1750059615, "env": {"SHELL": "/usr/local/bin/bash", "TERM": "xterm-256color"}, "title": "Terminal AI"}
2+
[1.433577, "o", "\u001b[?2004h\r\n\u001b[1m\u001b[34m07-shell-snippets/snippets/envsubst\u001b(B\u001b[m \u001b[32mfeat/envsubst-killport\u001b(B\u001b[m \u001b[31m!\u001b(B\u001b[m \u001b[35mconda/\u001b[1mbase\u001b[0m\u001b(B\u001b[m \r\n\u001b[1m\u001b[37m$\u001b(B\u001b[m "]
3+
[2.034277, "o", "k"]
4+
[2.274531, "o", "i"]
5+
[2.608128, "o", "l"]
6+
[2.748635, "o", "l"]
7+
[3.022153, "o", "p"]
8+
[3.081931, "o", "o"]
9+
[3.234455, "o", "r"]
10+
[3.29366, "o", "t"]
11+
[3.483957, "o", "\r\n"]
12+
[3.483991, "o", "\u001b[?2004l\r"]
13+
[3.48426, "o", "error: no port specified\r\nusage: killport <port>\r\n"]
14+
[3.558187, "o", "\u001b[?2004h\r\n\u001b[1m\u001b[34m07-shell-snippets/snippets/envsubst\u001b(B\u001b[m \u001b[32mfeat/envsubst-killport\u001b(B\u001b[m \u001b[31m!\u001b(B\u001b[m \u001b[35mconda/\u001b[1mbase\u001b[0m\u001b(B\u001b[m \r\n\u001b[1m\u001b[37m$\u001b(B\u001b[m "]
15+
[4.55078, "o", "k"]
16+
[4.733415, "o", "i"]
17+
[4.965858, "o", "l"]
18+
[5.100758, "o", "l"]
19+
[5.270919, "o", "p"]
20+
[5.33211, "o", "o"]
21+
[5.439241, "o", "r"]
22+
[5.535072, "o", "t"]
23+
[5.611154, "o", " "]
24+
[6.030778, "o", "3"]
25+
[6.197284, "o", "0"]
26+
[6.38131, "o", "0"]
27+
[6.538704, "o", "0"]
28+
[6.870086, "o", "\r\n"]
29+
[6.87021, "o", "\u001b[?2004l\r"]
30+
[6.913926, "o", "killed process using port 3000: /Applications/Docker.app/Contents/MacOS/com.docker.backend\r\n"]
31+
[7.006818, "o", "\u001b[?2004h\r\n\u001b[1m\u001b[34m07-shell-snippets/snippets/envsubst\u001b(B\u001b[m \u001b[32mfeat/envsubst-killport\u001b(B\u001b[m \u001b[31m!\u001b(B\u001b[m \u001b[35mconda/\u001b[1mbase\u001b[0m\u001b(B\u001b[m \r\n\u001b[1m\u001b[37m$\u001b(B\u001b[m "]
32+
[13.635868, "o", "\u0007"]
33+
[15.100458, "o", "^C"]
34+
[15.10082, "o", "\u001b[?2004l\r"]
35+
[15.101065, "o", "\u001b[?2004h\u001b[?2004l\r"]
36+
[15.101394, "o", "\r\n"]
37+
[15.172262, "o", "\u001b[?2004h\r\n\u001b[1m\u001b[34m07-shell-snippets/snippets/envsubst\u001b(B\u001b[m \u001b[32mfeat/envsubst-killport\u001b(B\u001b[m \u001b[31m!\u001b(B\u001b[m \u001b[35mconda/\u001b[1mbase\u001b[0m\u001b(B\u001b[m \r\n\u001b[1m\u001b[37m$\u001b(B\u001b[m "]
38+
[15.303846, "o", "e"]
39+
[15.467329, "o", "x"]
40+
[15.542469, "o", "i"]
41+
[15.626898, "o", "t"]
42+
[15.692584, "o", "\r\n"]
43+
[15.692791, "o", "\u001b[?2004l\r"]
44+
[15.692819, "o", "exit\r\n"]

0 commit comments

Comments
 (0)