Blob


1 # ksh
3 OpenBSD ksh (sometimes called opdksh or oksh) is the default shell on
4 OpenBSD, and is generally my go-to choince on other systems too. It has
5 a good ratio of features and simplicity
7 if [ "$TERM" = dumb ]; then
8 PS1='$ '
9 return
10 fi
12 Enable emacs-like command editing regardless of $EDITOR and csh-like
13 history expansion with !
15 set -o emacs
16 set -o csh-history
18 Talking about history, by default ksh won't store any, which is
19 unfortunate. I can't live without my C-r working!
21 HISTCONTROL=ignoredups:ignorespace
22 HISTFILE=$HOME/.history
23 HISTSIZE=10000
25 OpenBSD ksh has a limited support for programmed completions through
26 static lists. The completions are provided via an array called
27 complete_$progname; or complete_$progname_$nth for the nth argument.
29 Here's the completions for ssh and scp:
31 HOST_LIST=$(awk '/Host / {print $2}' ~/.ssh/config | xargs echo)
33 set -A complete_ssh -- $HOST_LIST
34 set -A complete_scp -- $HOST_LIST
36 and for kill(1) and pkill(1)
38 set -A complete_kill_1 -- -9 -HUP -INFO -KILL -TERM
39 set -A complete_pkill_2 -- -SIGHUP -SIGUSR1 -SIGUSR2 -SIGTERM -SIGKILL
41 and for vmd(8) if available
43 if test -f /usr/sbin/vmd && pgrep -fq /usr/sbin/vmd; then
44 set -A complete_vmctl_1 -- console load reload start stop \
45 reset status send receive
46 set -A complete_vmctl -- \
47 $(vmctl status | awk '!/NAME/{printf "%s ", $NF}')
48 fi
50 and for ifconfig(8)
52 command -v ifconfig >/dev/null && \
53 set -A complete_ifconfig_1 -- $(ifconfig | grep ^[a-z] | cut -d: -f1)
55 and for got(1)
57 command -v got >/dev/null && \
58 set -A complete_got_1 -- $(got -h 2>&1 | sed -n s/commands://p)
60 Tweak the output of ls
62 alias ls='ls -F'
64 Provide an easiest access to amused
66 alias a=amused
68 and to quit
70 alias q=exit
72 TCL manpages on OpenBSD are installed outside of the default MANPATH.
73 Since they have a lot of clashes with "standard" command (like `exec'),
74 define an alias to open specifically TCL8.6 man pages:
76 alias tm='man -M /usr/local/lib/tcl/tcl8.6/man'
78 reset(1) doesn't work as expected inside tmux: the old output can still
79 be consulted when scrolling. If I, lazy as I am, bother to type "reset"
80 I want to be sure that the history was cleared!
82 if [ -n "$TMUX" ]; then
83 alias reset='reset && tmux clear-history'
84 fi
86 CDPATH is super useful! I even wrote a post about it:
87 https://www.omarpolo.com/post/enjoying-cdpath.html
89 export CDPATH=".:$HOME/w:/usr/ports:/usr/ports/mystuff:$HOME/quicklisp/local-projects"
91 I love to hate gpg! It needs some special treatments to work and this
92 should also (finger crossed!) fix pinentry over ssh. I'm not sure it
93 works though, it's been a while since I've connected remotely to my
94 desktop.
96 export GPG_TTY=$(tty)
97 if [ -n "$SSH_CONNECTION" ]; then
98 export PINENTRY_USER_DATA="USE_CURSES=1"
99 fi
101 The BSDs have this incredibly useful signal available, it's a shame not
102 to use it!
104 case "$(uname)" in
105 *BSD) stty status ^T ;;
106 esac
108 I really like my prompt to be as minimal as possible. For some time
109 I've used a single colon `;' as prompt, it's really nice! At the moment
110 thought I'm usign a more plan9-esque percent sign, with an optional
111 hostname:
113 if [ "$(hostname)" = venera ]; then
114 PS1='% '
115 else
116 PS1='\h% '
117 fi
119 I got tired of trying to remember the set of flags for nc to walk to
120 Gemini servers, so here we are:
122 # "post" stdin to the gemini server
123 # usage: gem host [port]
124 gem()
126 host="${1:?missing host}"
127 port="${2:-1965}"
128 nc -c -Tnoverify "${host}" "${port}"
131 I think I've stolen these from someone. It makes a copy of the file and
132 launch an editor on the original file, incledibly useful when working
133 with ports (that's why doas!)
135 mgdiff()
137 if [ -z "$1" ]; then
138 printf "%s\n" "USAGE: mgdiff file" >&2
139 return
140 fi
141 doas cp -p "$1" "$1.orig.port"
142 doas mg "$1"
145 hist is a quick wrapper around history and grep to quickly search for a
146 previous command:
148 hist()
150 if [ -z "$1" ]; then
151 printf "%s\n" "USAGE: hist pattern" >&2
152 return 1
153 fi
154 history 0 | grep "$1"
157 clbin (the site) is a web pastebin that's easy to use from the command
158 line with curl. clbin (the function) is an easy way to share something,
159 just pipe it to clbin and it returns an url.
161 clbin()
163 curl -F 'clbin=<-' https://clbin.com
166 Some aliases I use when working with the OpenBSD port tree:
168 alias m="make"
169 alias mup="VISUAL=mg make update-patches"
170 alias mupl="make update-plist"
171 alias mpldc="make port-lib-depends-check"
172 alias pbuild="env MAKE_JOBS=5 time make"
173 alias build="pbuild 2>&1 | tee build"
174 alias pclean='make clean="package plist"'
176 This one is pretty sophisticated, I've stolen it from jca@
178 # check shared libs version
179 cshlib() {
180 local cnt=0
181 local f
183 for f in $(make show=SHARED_LIBS); do
184 [ "$((cnt++ % 2))" -eq 1 ] && continue
185 echo '===>' $f
186 /usr/src/lib/check_sym /usr/local/lib/lib$f.so* \
187 $(make show=WRKINST)/usr/local/lib/lib$f.so*
188 done
191 And even more aliases:
193 alias mopnew="mdirs ~/Maildir/op | grep -v rss | mlist -st | mthread -r | mseq -S"
195 for c in com rep fwd bnc; do
196 local _mvisual='mg -f auto-fill-mode'
198 alias m$c="VISUAL='$_mvisual' m$c"
199 alias o$c="m$c -from 'Omar Polo <op@openbsd.org>'"
200 done
202 And finally some aliases for mq
204 alias pnq="NQDIR=/tmp/ports/ nq "
205 alias pfq="NQDIR=/tmp/ports/ fq "
207 Stuff to use my own purritobin instance
209 : ${P_SERVER=paste.omarpolo.com}
210 : ${P_PORT=42069}
211 : ${P_TIME=week}
212 : ${P_MAXTIME=30}
214 shell client to upload a plaintext message
216 purr() {
217 curl --silent --max-time "${P_MAXTIME}" \
218 --data-binary "@${1:-/dev/stdin}" \
219 "${P_SERVER}:${P_PORT}/${P_TIME}"
222 shell client to upload an encrypted message
224 meow() {
225 key="$(openssl rand -hex 32)"
226 iv="$(openssl rand -hex 16)"
227 url="$(openssl enc -aes-256-cbc -K ${key} -iv ${iv} -e -base64 -A < ${1:-/dev/stdin} | purr)"
228 printf "%s\n" "${url%\/*}/paste.html#${url##*\/}_${key}_${iv}"
229 unset key iv url
232 ...and to decrypt it
234 meowd() {
235 url="$1"
236 baseurl="${url%\/*}"
237 vals="${url##*\#}"
238 paste=$(printf '%s\n' "${vals}" | cut -d_ -f1)
239 key=$(printf '%s\n' "${vals}" | cut -d _ -f2)
240 iv=$(printf '%s\n' "${vals}" | cut -d _ -f3)
241 curl --max-time "${P_MAXTIME}" --write-out "\n" --silent \
242 "${baseurl}/${paste}" | openssl enc -aes-256-cbc \
243 -base64 -d -K ${key} -iv ${iv}
244 unset url baseurl vals paste key iv
247 llama is also nice. It's possible to use it to cd too!
249 ll() {
250 cd "$(llama "$@")"
253 For extra-comfyness bind it to C-o
255 bind -m '^O=^U ll^M^Y'
257 find(1) is an invaluable tool and I use it all the time. walk is an
258 attempt to build a wrapper around some common usages of find that is a
259 little bit less verbose to use. The name is stolen from 9front, but the
260 implementation is completely different.
262 # usage: walk [dir] [type] [name regexp] [! command to execute]
263 walk()
265 if [ $# -eq 0 ]; then
266 find .
267 return
268 fi
270 local dir=.
271 local type=
272 local name=\*
274 if [ -n "$1" -a -d "$1" ]; then
275 dir="$1"
276 shift
277 fi
279 case "$1" in
280 b|c|d|f|l|p|s)
281 type="-type $1"
282 shift
283 esac
285 if [ -n "$1" -a "x$1" != "x!" ]; then
286 name="$1"
287 shift
288 fi
290 if [ "x$1" = x! ]; then
291 shift
292 fi
294 if [ $# -eq 0 ]; then
295 find "$dir" $type -iname "$name"
296 else
297 find "$dir" $type -iname "$name" -exec "$@" {} +
298 fi
301 Sometimes it's useful to have a local postgresql database for testing. I've stolen this trick from
302 => https://jamey.thesharps.us/2019/05/29/per-project-postgres/ Jamey Thesharps "Per-project postgres" blog post
304 localpg() {
305 export PGDATA="$(pwd)/postgres"
306 export PGHOST="$PGDATA"
308 if [ ! -d "$PGDATA" ]; then
309 initdb
310 cat >> "$PGDATA/postgresql.conf" <<-EOF
311 listen_addresses = ''
312 unix_socket_directories = '$PGHOST'
313 EOF
314 echo "CREATE DATABASE $USER;" | postgres --single -E postgres
315 fi