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
12 Enable emacs-like command editing regardless of $EDITOR and csh-like
13 history expansion with !
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
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}')
52 command -v ifconfig >/dev/null && \
53 set -A complete_ifconfig_1 -- $(ifconfig | grep ^[a-z] | cut -d: -f1)
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
64 Provide an easiest access to amused
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'
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
97 if [ -n "$SSH_CONNECTION" ]; then
98 export PINENTRY_USER_DATA="USE_CURSES=1"
101 The BSDs have this incredibly useful signal available, it's a shame not
105 *BSD) stty status ^T ;;
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
113 if [ "$(hostname)" = venera ]; then
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]
126 host="${1:?missing host}"
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!)
138 printf "%s\n" "USAGE: mgdiff file" >&2
141 doas cp -p "$1" "$1.orig.port"
145 hist is a quick wrapper around history and grep to quickly search for a
151 printf "%s\n" "USAGE: hist pattern" >&2
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.
163 curl -F 'clbin=<-' https://clbin.com
166 Some aliases I use when working with the OpenBSD port tree:
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
183 for f in $(make show=SHARED_LIBS); do
184 [ "$((cnt++ % 2))" -eq 1 ] && continue
186 /usr/src/lib/check_sym /usr/local/lib/lib$f.so* \
187 $(make show=WRKINST)/usr/local/lib/lib$f.so*
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>'"
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}
214 shell client to upload a plaintext message
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
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}"
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!
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]
265 if [ $# -eq 0 ]; then
274 if [ -n "$1" -a -d "$1" ]; then
285 if [ -n "$1" -a "x$1" != "x!" ]; then
290 if [ "x$1" = x! ]; then
294 if [ $# -eq 0 ]; then
295 find "$dir" $type -iname "$name"
297 find "$dir" $type -iname "$name" -exec "$@" {} +
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
305 export PGDATA="$(pwd)/postgres"
306 export PGHOST="$PGDATA"
308 if [ ! -d "$PGDATA" ]; then
310 cat >> "$PGDATA/postgresql.conf" <<-EOF
311 listen_addresses = ''
312 unix_socket_directories = '$PGHOST'
314 echo "CREATE DATABASE $USER;" | postgres --single -E postgres