

,.......... ..........,
,..,' '.' ',..,
,' ,' : ', ',
,' ,' : ', ',
,' ,' : ', ',
,' ,'............., : ,.............', ',
,' '............ '.' ............' ',
'''''''''''''''''';''';''''''''''''''''''
'''
-=[ typewriters ]=- 1/98
.-------.
.-------. _|~~ ~~ |_
_|~~ ~~ |_ .-------. =(_|_______|_)
=(_|_______|_)= _|~~ ~~ |_ |:::::::::| .-------.
|:::::::::| =(_|_______|_) |:::::::[]| _|~~ ~~ |_
|:::::::[]| |:::::::::| |o=======.| =(_|_______|_)
|o=======.| |:::::::[]| `"""""""""` |:::::::::|
jgs `"""""""""` |o=======.| |:::::::[]|
mod. by Paul Buetow `"""""""""` |o=======.|
`"""""""""`
<< template::inline::toc
declare -xr HTML_THEME_DIR=./extras/html/themes/simple
__..._ _...__
_..-" `Y` "-._
\ Once upon | /
\\ a time..| //
\\\ | ///
\\\ _..---.|.---.._ ///
jgs \\`_..---.Y.---.._`//
||====================================================================|| ||//$\\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\//$\\|| ||(100)==================| FEDERAL SPONSOR NOTE |================(100)|| ||\\$// ~ '------========--------' \\$//|| ||<< / /$\ // ____ \\ \ >>|| ||>>| 12 //L\\ // ///..) \\ L38036133B 12 |<<|| ||<<| \\ // || <|| >\ || |>>|| ||>>| \$/ || $$ --/ || One Hundred |<<|| ||<<| L38036133B *\\ |\_/ //* series |>>|| ||>>| 12 *\\/___\_//* 1989 |<<|| ||<<\ Open Source ______/Franklin\________ Supporting />>|| ||//$\ ~| SPONSORING AND FUNDING |~ /$\\|| ||(100)=================== AWESOME OPEN SOURCE =================(100)|| ||\\$//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\\$//|| ||====================================================================||
,---,---,---,---,---,---,---,---,---,---,---,---,---,-------,
|1/2| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | + | ' | <- |
|---'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-----|
| ->| | Q | W | E | R | T | Y | U | I | O | P | ] | ^ | |
|-----',--',--',--',--',--',--',--',--',--',--',--',--'| |
| Caps | A | S | D | F | G | H | J | K | L | \ | [ | * | |
|----,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'-,-'---'----|
| | < | Z | X | C | V | B | N | M | , | . | - | |
|----'-,-',--'--,'---'---'---'---'---'---'-,-'---',--,------|
| ctrl | | alt | |altgr | | ctrl |
'------' '-----'--------------------------'------' '------'
Nieminen Mika





,.......... ..........,
,..,' '.' ',..,
,' ,' : ', ',
,' ,' : ', ',
,' ,' : ', ',
,' ,'............., : ,.............', ',
,' '............ '.' ............' ',
'''''''''''''''''';''';''''''''''''''''''
'''
/\_/\ WHOA!! ( o.o ) > ^ < / - \ / \ /______\ \
% traceroute bad.horse traceroute to bad.horse (162.252.205.157), 30 hops max, 60 byte packets 1 dsldevice.lan (192.168.1.1) 5.712 ms 5.800 ms 6.466 ms 2 87-243-116-2.ip.btc-net.bg (87.243.116.2) 8.017 ms 7.506 ms 8.432 ms 3 * * * 4 * * * 5 xe-1-2-0.mpr1.fra4.de.above.net (80.81.194.26) 39.952 ms 40.155 ms 40.139 ms 6 ae12.cs1.fra6.de.eth.zayo.com (64.125.26.172) 128.014 ms * * 7 * * * 8 * * * 9 ae10.cs1.lhr15.uk.eth.zayo.com (64.125.29.17) 120.625 ms 121.117 ms 121.050 ms 10 * * * 11 * * * 12 * * * 13 ae5.mpr1.tor3.ca.zip.zayo.com (64.125.23.118) 192.605 ms 205.741 ms 203.607 ms 14 64.124.217.237.IDIA-265104-ZYO.zip.zayo.com (64.124.217.237) 204.673 ms 134.674 ms 131.442 ms 15 * * * 16 67.223.96.90 (67.223.96.90) 128.245 ms 127.844 ms 127.843 ms 17 bad.horse (162.252.205.130) 128.194 ms 122.854 ms 121.786 ms 18 bad.horse (162.252.205.131) 128.831 ms 128.341 ms 186.559 ms 19 bad.horse (162.252.205.132) 185.716 ms 180.121 ms 180.042 ms 20 bad.horse (162.252.205.133) 203.170 ms 203.076 ms 203.168 ms 21 he.rides.across.the.nation (162.252.205.134) 203.115 ms 141.830 ms 141.799 ms 22 the.thoroughbred.of.sin (162.252.205.135) 147.965 ms 148.230 ms 170.478 ms 23 he.got.the.application (162.252.205.136) 165.161 ms 164.939 ms 159.085 ms 24 that.you.just.sent.in (162.252.205.137) 162.310 ms 158.569 ms 158.896 ms 25 it.needs.evaluation (162.252.205.138) 162.927 ms 163.046 ms 163.085 ms 26 so.let.the.games.begin (162.252.205.139) 233.363 ms 233.545 ms 233.317 ms 27 a.heinous.crime (162.252.205.140) 237.745 ms 233.614 ms 233.740 ms 28 a.show.of.force (162.252.205.141) 237.974 ms 176.085 ms 175.927 ms 29 a.murder.would.be.nice.of.course (162.252.205.142) 181.838 ms 181.858 ms 182.059 ms 30 bad.horse (162.252.205.143) 187.731 ms 187.416 ms 187.532 ms
#include <stdio.h>
int main(void) {
int array[5] = { 1, 2, 3, 4, 5 };
for (int i = 0; i < 5; i++)
printf("%d\n", array[i]);
for (int i = 0; i < 5; i++)
printf("%d\n", i[array]);
for (int i = 0; i < 5; i++)
printf("%d\n", *(i + array));
}
#include <stdio.h>
int main(void) {
int $array[5] = { 1, 2, 3, 4, 5 };
for (int $i = 0; $i < 5; $i++)
printf("%d\n", $array[$i]);
for (int $i = 0; $i < 5; $i++)
printf("%d\n", $i[$array]);
for (int $i = 0; $i < 5; $i++)
printf("%d\n", *($i + $array));
}
#!/usr/bin/ksh93
typeset -T Point_t=(
integer -h 'x coordinate' x=0
integer -h 'y coordinate' y=0
typeset -h 'point color' color="red"
function getcolor {
print -r ${_.color}
}
function setcolor {
_.color=$1
}
setxy() {
_.x=$1; _.y=$2
}
getxy() {
print -r "(${_.x},${_.y})"
}
)
Point_t point
echo "Initial coordinates are (${point.x},${point.y}). Color is ${point.color}"
point.setxy 5 6
point.setcolor blue
echo "New coordinates are ${point.getxy}. Color is ${point.getcolor}"
exit 0
package main
import "fmt"
func main() {
var i int
f := func() *int {
return &i
}
*f()++
fmt.Println(i)
}
def _token:
def _re($re; f):
( . as {$remain, $string_stack}
| $remain
| match($re; "m").string
| f as $token
| { result: ($token | del(.string_stack))
, remain: $remain[length:]
, string_stack:
( if $token.string_stack == null then $string_stack
else $token.string_stack
end
)
}
);
if .remain == "" then empty
else
( . as {$string_stack}
| _re("^\\s+"; {whitespace: .})
// _re("^#[^\n]*"; {comment: .})
// _re("^\\.[_a-zA-Z][_a-zA-Z0-9]*"; {index: .[1:]})
// _re("^[_a-zA-Z][_a-zA-Z0-9]*"; {ident: .})
// _re("^@[_a-zA-Z][_a-zA-Z0-9]*"; {at_ident: .})
// _re("^\\$[_a-zA-Z][_a-zA-Z0-9]*"; {binding: .})
# 1.23, .123, 123e2, 1.23e2, 123E2, 1.23e+2, 1.23E-2 or 123
// _re("^(?:[0-9]*\\.[0-9]+|[0-9]+)(?:[eE][-\\+]?[0-9]+)?"; {number: .})
// _re("^\"(?:[^\"\\\\]|\\\\.)*?\\\\\\(";
( .[1:-2]
| _unescape
| {string_start: ., string_stack: ($string_stack+["\\("])}
)
)
.
.
.
(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t] )+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?: \r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:( ?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\0 31]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\ >(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+ (?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?: (?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z |(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n) ?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\ r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n) ?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t] )*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])* )(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t] )+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*) *:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+ |\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r \n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?: \r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t >))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031 >+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\]( ?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(? :(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(? :\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(? :(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)? [ \t]))*"(?:(?:\r\n)?[ \t])*)*:(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]| \\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<> @,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|" (?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t] )*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\ ".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(? :[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[ \]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000- \031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|( ?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,; :\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([ ^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\" .\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\ >\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\ [\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\ r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\] |\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \0 00-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\ .|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@, ;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(? :[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])* (?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\". \[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[ ^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\] >))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)(?:,\s*( ?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\ ".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:( ?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[ \["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t >)*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t >)+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(? :\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+| \Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?: [^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\ >]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n) ?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\[" ()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n) ?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<> @,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@, ;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t] )*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\ ".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)? (?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\". \[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?: \r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\[ "()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t]) *))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t]) +|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\ .(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z |(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:( ?:\r\n)?[ \t])*))*)?;\s*)
_______
|.-----.|
|| Tmux||
||_.-._||
`--)-(--`
__[=== o]___
|:::::::::::|\
jgs `-=========-`()
mod. by Paul B.
alias tm=tmux alias tl='tmux list-sessions' alias tn=tmux::new alias ta=tmux::attach alias tx=tmux::remote alias ts=tmux::search alias tssh=tmux::cluster_ssh
# Create new session and if alread exists attach to it
tmux::new () {
readonly session=$1
local date=date
if where gdate &>/dev/null; then
date=gdate
fi
tmux::cleanup_default
if [ -z "$session" ]; then
tmux::new T$($date +%s)
else
tmux new-session -d -s $session
tmux -2 attach-session -t $session || tmux -2 switch-client -t $session
fi
}
alias tn=tmux::new
tmux::cleanup_default () {
local s
tmux list-sessions | grep '^T.*: ' | grep -F -v attached |
cut -d: -f1 | while read -r s; do
echo "Killing $s"
tmux kill-session -t "$s"
done
}
tmux::attach () {
readonly session=$1
if [ -z "$session" ]; then
tmux attach-session || tmux::new
else
tmux attach-session -t $session || tmux::new $session
fi
}
alias ta=tmux::attach
tmux::remote () {
readonly server=$1
tmux new -s $server "ssh -t $server 'tmux attach-session || tmux'" || \
tmux attach-session -d -t $server
}
alias tr=tmux::remote
set-option -g prefix C-g
tmux::search () {
local -r session=$(tmux list-sessions | fzf | cut -d: -f1)
if [ -z "$TMUX" ]; then
tmux attach-session -t $session
else
tmux switch -t $session
fi
}
alias ts=tmux::search

tmux::cluster_ssh () {
if [ -f "$1" ]; then
tmux::tssh_from_file $1
return
fi
tmux::tssh_from_argument $@
}
alias tssh=tmux::cluster_ssh
tmux::tssh_from_argument () {
local -r session=$1; shift
local first_server=$1; shift
tmux new-session -d -s $session "ssh -t $first_server"
if ! tmux list-session | grep "^$session:"; then
echo "Could not create session $session"
return 2
fi
for server in "${@[@]}"; do
tmux split-window -t $session "tmux select-layout tiled; ssh -t $server"
done
tmux setw -t $session synchronize-panes on
tmux -2 attach-session -t $session | tmux -2 switch-client -t $session
}
bind-key p setw synchronize-panes off bind-key P setw synchronize-panes on
tmux::tssh_from_file () {
local -r serverlist=$1; shift
local -r session=$(basename $serverlist | cut -d. -f1)
tmux::tssh_from_argument $session $(awk '{ print $1} ' $serverlist | sed 's/.lan./.lan/g')
}
$ tssh fish blowfish.buetow.org fishfinger.buetow.org \
fishbone.buetow.org user@octopus.buetow.org
$ tssh manyservers.txt
bind-key -T copy-mode-vi 'v' send -X begin-selection bind-key -T copy-mode-vi 'y' send -X copy-selection-and-cancel
source ~/.config/tmux/tmux.local.conf set-option -g allow-rename off set-option -g history-limit 100000 set-option -g status-bg '#444444' set-option -g status-fg '#ffa500' set-option -s escape-time 0
set-window-option -g mode-keys vi bind-key -T copy-mode-vi 'v' send -X begin-selection bind-key -T copy-mode-vi 'y' send -X copy-selection-and-cancel
bind-key h select-pane -L bind-key j select-pane -D bind-key k select-pane -U bind-key l select-pane -R bind-key H resize-pane -L 5 bind-key J resize-pane -D 5 bind-key K resize-pane -U 5 bind-key L resize-pane -R 5
bind-key c new-window -c '#{pane_current_path}'
bind-key F new-window -n "session-switcher" "tmux list-sessions | fzf | cut -d: -f1 | xargs tmux switch-client -t"
bind-key T choose-tree

bind-key p setw synchronize-panes off bind-key P setw synchronize-panes on bind-key r source-file ~/.config/tmux/tmux.conf \; display-message "tmux.conf reloaded"
Art by Laura Brown .'`~~~~~~~~~~~`'. ( .'11 12 1'. ) | :10 \ 2: | | :9 @-> 3: | | :8 4; | '. '..7 6 5..' .' ~-------------~ ldb
Cluster :UK, :uk01 do
Customer.C1A1.segments.volumes.each do |volume|
puts volume.usage_stats
volume.move_off! if volume.over_subscribed?
end
end
,.......... ..........,
,..,' '.' ',..,
,' ,' : ', ',
,' ,' : ', ',
,' ,' : ', ',
,' ,'............., : ,.............', ',
,' '............ '.' ............' ',
'''''''''''''''''';''';''''''''''''''''''
'''
Art by Michael J. Penick (mod. by Paul B.)
ACME-sky
__________
/ nsd tower\ (
/____________\ (\) awk-ward
|:_:_:_:_:_| )) plant
|_:_,--.:_:| dig-bubble (\// )
|:_:|__|_:_| relayd-castle _ ) )) ((
_ |_ _ :_:| _ _ _ (_) (((( /)\`
| |_| |_| | _| | |_| |_| | o \\)) (( (
\_:_:_:_:/|_|_|_|\:_:_:_:_/ . (( ))))
|_,-._:_:_:_:_:_:_:_.-,_| )) ((//
|:|_|:_:_:,---,:_:_:|_|:| ,-. )/
|_:_:_:_,'puffy `,_:_:_:_| _ o ,;'))((
|:_:_:_/ _ | _ \_:_:_:| (_O (( ))
_____|_:_:_| (o)-(o) |_:_:_|--'`-. ,--. ksh under-water (((\'/
', ;|:_:_:| -( .-. )- |:_:_:| ', ; `--._\ /,---.~ goat \`))
. ` |_:_:_| \`-'/ |_:_:_|. ` . ` /()\.__( ) .,-----'`-\(( sed-root
', ;|:_:_:| `-' |:_:_:| ', ; ', ; `--'| \ ', ; ', ; ',')).,--
. ` MJP ` . ` . ` . ` . httpd-soil ` . . ` . ` . ` . ` . `
', ; ', ; ', ; ', ; ', ; ', ; ', ; ', ; ', ; ', ; ', ; ', ; ', ; ', ;
#!/bin/ksh
ZONES_DIR=/var/nsd/zones/master/
DEFAULT_MASTER=fishfinger.buetow.org
DEFAULT_STANDBY=blowfish.buetow.org
determine_master_and_standby () {
local master=$DEFAULT_MASTER
local standby=$DEFAULT_STANDBY
.
.
.
local -i health_ok=1
if ! ftp -4 -o - https://$master/index.txt | grep -q "Welcome to $master"; then
echo "https://$master/index.txt IPv4 health check failed"
health_ok=0
elif ! ftp -6 -o - https://$master/index.txt | grep -q "Welcome to $master"; then
echo "https://$master/index.txt IPv6 health check failed"
health_ok=0
fi
if [ $health_ok -eq 0 ]; then
local tmp=$master
master=$standby
standby=$tmp
fi
.
.
.
}
fishfinger$ grep failover /var/nsd/zones/master/foo.zone.zone
300 IN A 46.23.94.99 ; Enable failover
300 IN AAAA 2a03:6000:6f67:624::99 ; Enable failover
www 300 IN A 46.23.94.99 ; Enable failover
www 300 IN AAAA 2a03:6000:6f67:624::99 ; Enable failover
standby 300 IN A 23.88.35.144 ; Enable failover
standby 300 IN AAAA 2a01:4f8:c17:20f1::42 ; Enable failover
transform () {
sed -E '
/IN A .*; Enable failover/ {
/^standby/! {
s/^(.*) 300 IN A (.*) ; (.*)/\1 300 IN A '$(cat /var/nsd/run/master_a)' ; \3/;
}
/^standby/ {
s/^(.*) 300 IN A (.*) ; (.*)/\1 300 IN A '$(cat /var/nsd/run/standby_a)' ; \3/;
}
}
/IN AAAA .*; Enable failover/ {
/^standby/! {
s/^(.*) 300 IN AAAA (.*) ; (.*)/\1 300 IN AAAA '$(cat /var/nsd/run/master_aaaa)' ; \3/;
}
/^standby/ {
s/^(.*) 300 IN AAAA (.*) ; (.*)/\1 300 IN AAAA '$(cat /var/nsd/run/standby_aaaa)' ; \3/;
}
}
/ ; serial/ {
s/^( +) ([0-9]+) .*; (.*)/\1 '$(date +%s)' ; \3/;
}
'
}
#! Race condition !#
if [ -f $zone_file.bak ]; then
mv $zone_file.bak $zone_file
fi
cat $zone_file | transform > $zone_file.new.tmp
grep -v ' ; serial' $zone_file.new.tmp > $zone_file.new.noserial.tmp
grep -v ' ; serial' $zone_file > $zone_file.old.noserial.tmp
echo "Has zone $zone_file changed?"
if diff -u $zone_file.old.noserial.tmp $zone_file.new.noserial.tmp; then
echo "The zone $zone_file hasn't changed"
rm $zone_file.*.tmp
return 0
fi
cp $zone_file $zone_file.bak
mv $zone_file.new.tmp $zone_file
rm $zone_file.*.tmp
echo "Reloading nsd"
nsd-control reload
if ! zone_is_ok $zone; then
echo "Rolling back $zone_file changes"
cp $zone_file $zone_file.invalid
mv $zone_file.bak $zone_file
echo "Reloading nsd"
nsd-control reload
zone_is_ok $zone
return 3
fi
for cleanup in invalid bak; do
if [ -f $zone_file.$cleanup ]; then
rm $zone_file.$cleanup
fi
done
echo "Failover of zone $zone to $MASTER completed"
return 1
# Weekly auto-failover for Let's Encrypt automation
local -i -r week_of_the_year=$(date +%U)
if [ $(( week_of_the_year % 2 )) -eq 0 ]; then
local tmp=$master
master=$standby
standby=$tmp
fi



FISHKISSFISHKIS
SFISHKISSFISHKISSFISH F
ISHK ISSFISHKISSFISHKISS FI
SHKISS FISHKISSFISHKISSFISS FIS
HKISSFISHKISSFISHKISSFISHKISSFISH KISS
FISHKISSFISHKISSFISHKISSFISHKISS FISHK
SSFISHKISSFISHKISSFISHKISSFISHKISSF
ISHKISSFISHKISSFISHKISSFISHKISSF ISHKI
SSFISHKISSFISHKISSFISHKISSFISHKIS SFIS
HKISSFISHKISSFISHKISSFISHKISS FIS
HKISSFISHKISSFISHKISSFISHK IS
SFISHKISSFISHKISSFISH K
ISSFISHKISSFISHK
$ doas installboot sd0 # Update the bootloader (not for every upgrade required) $ doas sysupgrade # Update all binaries (including Kernel)
$ doas sysmerge # Update system configuration files $ doas pkg_add -u # Update all packages $ doas reboot # Just in case, reboot one more time
..--""""----..
.-" ..--""""--.j-.
.-" .-" .--.""--..
.-" .-" ..--"-. \/ ;
.-" .-"_.--..--"" ..--' "-. :
.' .' / `. \..--"" __ _ \ ;
:.__.-" \ / .' ( )"-. Y
; ;: ( ) ( ). \
.': /:: : \ \
.'.-"\._ _.-" ; ; ( ) .-. ( ) \
" `.""" .j" : : \ ; ; \
bug /"""""/ ; ( ) "" :.( ) \
/\ / : \ \`.: _ \
: `. / ; `( ) (\/ :" \ \
\ `. : "-.(_)_.' t-' ;
\ `. ; ..--":
`. `. : ..--"" :
`. "-. ; ..--"" ;
`. "-.:_..--"" ..--"
`. : ..--""
"-. : ..--""
"-.;_..--""
'\ '\ '\ . . |>18>>
\ \ \ . ' . |
O>> O>> O>> . 'o |
\ .\. .. .\. .. . |
/\ . /\ . /\ . . |
/ / . / / .'. / / .' . |
jgs^^^^^^^`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Art by Joan Stark, mod. by Paul Buetow
#!/usr/bin/env bash
log () {
local -r level="$1"; shift
local -r message="$1"; shift
local -i pid="$$"
local -r callee=${FUNCNAME[1]}
local -r stamp=$(date +%Y%m%d-%H%M%S)
echo "$level|$stamp|$pid|$callee|$message" >&2
}
at_home_friday_evening () {
log INFO 'One Peperoni Pizza, please'
}
at_home_friday_evening
❯ ./logexample.sh INFO|20231210-082732|123002|at_home_friday_evening|One Peperoni Pizza, please

#!/usr/bin/env bash
outer() {
inner() {
echo 'Intel inside!'
}
inner
}
inner
outer
inner
❯ ./inner.sh /tmp/inner.sh: line 10: inner: command not found Intel inside! Intel inside!
#!/usr/bin/env bash
outer1() {
inner() {
echo 'Intel inside!'
}
inner
}
outer2() {
inner() {
echo 'Wintel inside!'
}
inner
}
outer1
inner
outer2
inner
❯ ./inner2.sh Intel inside! Intel inside! Wintel inside! Wintel inside!
#!/usr/bin/env bash
some_expensive_operations() {
echo "Doing expensive operations with '$1' from pid $$"
}
for i in {0..9}; do echo $i; done \
| xargs -P10 -I{} bash -c 'some_expensive_operations "{}"'
❯ ./xargs.sh bash: line 1: some_expensive_operations: command not found bash: line 1: some_expensive_operations: command not found bash: line 1: some_expensive_operations: command not found bash: line 1: some_expensive_operations: command not found bash: line 1: some_expensive_operations: command not found bash: line 1: some_expensive_operations: command not found bash: line 1: some_expensive_operations: command not found bash: line 1: some_expensive_operations: command not found bash: line 1: some_expensive_operations: command not found bash: line 1: some_expensive_operations: command not found
#!/usr/bin/env bash
some_expensive_operations() {
echo "Doing expensive operations with '$1' from pid $$"
}
export -f some_expensive_operations
for i in {0..9}; do echo $i; done \
| xargs -P10 -I{} bash -c 'some_expensive_operations "{}"'
❯ ./xargs.sh Doing expensive operations with '0' from pid 132831 Doing expensive operations with '1' from pid 132832 Doing expensive operations with '2' from pid 132833 Doing expensive operations with '3' from pid 132834 Doing expensive operations with '4' from pid 132835 Doing expensive operations with '5' from pid 132836 Doing expensive operations with '6' from pid 132837 Doing expensive operations with '7' from pid 132838 Doing expensive operations with '8' from pid 132839 Doing expensive operations with '9' from pid 132840
#!/usr/bin/env bash
some_other_function() {
echo "$1"
}
some_expensive_operations() {
some_other_function "Doing expensive operations with '$1' from pid $$"
}
export -f some_expensive_operations
for i in {0..9}; do echo $i; done \
| xargs -P10 -I{} bash -c 'some_expensive_operations "{}"'
#!/usr/bin/env bash
foo() {
local foo=bar # Declare local/dynamic variable
bar
echo "$foo"
}
bar() {
echo "$foo"
foo=baz
}
foo=foo # Declare global variable
foo # Call function foo
echo "$foo"
❯ ./dynamic.sh bar baz foo
#!/usr/bin/env bash
declare -r foo=foo
declare -r bar=bar
if [ "$foo" = foo ]; then
if [ "$bar" = bar ]; then
echo ok1
fi
fi
if [ "$foo" = foo ] && [ "$bar" == bar ]; then
echo ok2a
fi
[ "$foo" = foo ] && [ "$bar" == bar ] && echo ok2b
if [[ "$foo" = foo && "$bar" == bar ]]; then
echo ok3a
fi
[[ "$foo" = foo && "$bar" == bar ]] && echo ok3b
if test "$foo" = foo && test "$bar" = bar; then
echo ok4a
fi
test "$foo" = foo && test "$bar" = bar && echo ok4b
❯ ./if.sh ok1 ok2a ok2b ok3a ok3b ok4a ok4b
#!/usr/bin/env bash # Single line comment # These are two single line # comments one after another : <<COMMENT This is another way a multi line comment could be written! COMMENT
#!/usr/bin/env bash echo foo echo echo baz >> $0 echo bar
❯ ./if.sh foo bar baz ❯ cat if.sh #!/usr/bin/env bash echo foo echo echo baz >> $0 echo bar echo baz
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣾⣷⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⣾⠿⠿⠿⠶⠾⠿⠿⣿⣿⣿⣿⣿⣿⠿⠿⠶⠶⠿⠿⠿⣷⠀⠀⠀⠀ ⠀⠀⠀⣸⢿⣆⠀⠀⠀⠀⠀⠀⠀⠙⢿⡿⠉⠀⠀⠀⠀⠀⠀⠀⣸⣿⡆⠀⠀⠀ ⠀⠀⢠⡟⠀⢻⣆⠀⠀⠀⠀⠀⠀⠀⣾⣧⠀⠀⠀⠀⠀⠀⠀⣰⡟⠀⢻⡄⠀⠀ ⠀⢀⣾⠃⠀⠀⢿⡄⠀⠀⠀⠀⠀⢠⣿⣿⡀⠀⠀⠀⠀⠀⢠⡿⠀⠀⠘⣷⡀⠀ ⠀⣼⣏⣀⣀⣀⣈⣿⡀⠀⠀⠀⠀⣸⣿⣿⡇⠀⠀⠀⠀⢀⣿⣃⣀⣀⣀⣸⣧⠀ ⠀⢻⣿⣿⣿⣿⣿⣿⠃⠀⠀⠀⠀⣿⣿⣿⣿⠀⠀⠀⠀⠈⢿⣿⣿⣿⣿⣿⡿⠀ ⠀⠀⠉⠛⠛⠛⠋⠁⠀⠀⠀⠀⢸⣿⣿⣿⣿⡆⠀⠀⠀⠀⠈⠙⠛⠛⠛⠉⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⣿⣿⣿⣿⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⣿⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠴⠶⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠶⠦⠀⠀
,.......... ..........,
,..,' '.' ',..,
,' ,' : ', ',
,' ,' : ', ',
,' ,' : ', ',
,' ,'............., : ,.............', ',
,' '............ '.' ............' ',
'''''''''''''''''';''';''''''''''''''''''
'''
___ .---------.._
______!fsc!_....-' .g8888888p. '-------....._
.' // .g8: :8p..---....___ \'.
| foo.zone // () d88: :88b|==========! !|
| // 888: :888|==========| !|
|___ \\_______'T88888888888P''----------'//|
| \ """"""""""""""""""""""""""""""""""/ |
| !...._____ .="""=. .[] ____...! |
| / ! .g$p. ! .[] : |
| ! : $$$$$ : .[] : |
| !irregular.ninja ! 'T$P' ! .[] '.|
| \__ "=._.=" .() __ |
|.--' '----._______________________.----' '--.|
'._____________________________________________.'
% sudo dnf install -y ImageMagick make git
% git clone https://codeberg.org/snonux/photoalbum Cloning into 'photoalbum'... remote: Enumerating objects: 1624, done. remote: Total 1624 (delta 0), reused 0 (delta 0), pack-reused 1624 Receiving objects: 100% (1624/1624), 193.36 KiB | 1.49 MiB/s, done. Resolving deltas: 100% (1227/1227), done. % cd photoalbum /home/paul/photoalbum % make cut -d' ' -f2 changelog | head -n 1 | sed 's/(//;s/)//' > .version test ! -d ./bin && mkdir ./bin || exit 0 sed "s/PHOTOALBUMVERSION/$(cat .version)/" src/photoalbum.sh > ./bin/photoalbum chmod 0755 ./bin/photoalbum % sudo make install test ! -d /usr/bin && mkdir -p /usr/bin || exit 0 cp ./bin/* /usr/bin test ! -d /usr/share/photoalbum/templates && mkdir -p /usr/share/photoalbum/templates || exit 0 cp -R ./share/templates /usr/share/photoalbum/ test ! -d /etc/default && mkdir -p /etc/default || exit 0 cp ./src/photoalbum.default.conf /etc/default/photoalbum
% photoalbum version This is Photoalbum Version 0.5.1
% mkdir irregular.ninja % cd irregular.ninja % # cp -Rpv ~/Photos/your-photos ./incoming
photoalbum clean|generate|version [rcfile] photoalbum photoalbum makemake
% photoalbum makemake You may now customize ./photoalbumrc and run make % cat Makefile all: photoalbum generate photoalbumrc clean: photoalbum clean photoalbumrc % cat photoalbumrc # The title of the photoalbum TITLE='A simple Photoalbum' # Thumbnail height geometry THUMBHEIGHT=300 # Normal geometry height (when viewing photo). Uncomment, to keep original size. HEIGHT=1200 # Max previews per page. MAXPREVIEWS=40 # Randomly shuffle all previews. # SHUFFLE=yes # Diverse directories, need to be full paths, not relative! INCOMING_DIR=$(pwd)/incoming DIST_DIR=$(pwd)/dist TEMPLATE_DIR=/usr/share/photoalbum/templates/default #TEMPLATE_DIR=/usr/share/photoalbum/templates/minimal # Includes a .tar of the incoming dir in the dist, can be yes or no TARBALL_INCLUDE=yes TARBALL_SUFFIX=.tar TAR_OPTS='-c' # Some debugging options #set -e #set -x
--- photoalbumrc 2023-10-29 21:42:00.894202045 +0200 +++ photoalbumrc.new 2023-06-04 10:40:08.030994440 +0300 @@ -1,23 +1,24 @@ # The title of the photoalbum -TITLE='A simple Photoalbum' +TITLE='Irregular.Ninja' # Thumbnail height geometry -THUMBHEIGHT=300 +THUMBHEIGHT=400 # Normal geometry height (when viewing photo). Uncomment, to keep original size. -HEIGHT=1200 +HEIGHT=1800 # Max previews per page. MAXPREVIEWS=40 -# Randomly shuffle all previews. -# SHUFFLE=yes +# Randomly shuffle +SHUFFLE=yes # Diverse directories, need to be full paths, not relative! -INCOMING_DIR=$(pwd)/incoming +INCOMING_DIR=~/Nextcloud/Photos/irregular.ninja DIST_DIR=$(pwd)/dist TEMPLATE_DIR=/usr/share/photoalbum/templates/default #TEMPLATE_DIR=/usr/share/photoalbum/templates/minimal # Includes a .tar of the incoming dir in the dist, can be yes or no -TARBALL_INCLUDE=yes +TARBALL_INCLUDE=no TARBALL_SUFFIX=.tar TAR_OPTS='-c'
% make photoalbum generate photoalbumrc Processing 1055079_cool-water-wallpapers-hd-hd-desktop-wal.jpg to /home/paul/irregular.ninja/dist/photos/1055079_cool-water-wallpapers-hd-hd-desktop-wal.jpg Processing 11271242324.jpg to /home/paul/irregular.ninja/dist/photos/11271242324.jpg Processing 11271306683.jpg to /home/paul/irregular.ninja/dist/photos/11271306683.jpg Processing 13950707932.jpg to /home/paul/irregular.ninja/dist/photos/13950707932.jpg Processing 14077406487.jpg to /home/paul/irregular.ninja/dist/photos/14077406487.jpg Processing 14859380100.jpg to /home/paul/irregular.ninja/dist/photos/14859380100.jpg Processing 14869239578.jpg to /home/paul/irregular.ninja/dist/photos/14869239578.jpg Processing 14879132910.jpg to /home/paul/irregular.ninja/dist/photos/14879132910.jpg . . . Generating /home/paul/irregular.ninja/dist/html/7-4.html Creating thumb /home/paul/irregular.ninja/dist/thumbs/20211130_091051.jpg Creating blur /home/paul/irregular.ninja/dist/blurs/20211130_091051.jpg Generating /home/paul/irregular.ninja/dist/html/page-7.html Generating /home/paul/irregular.ninja/dist/html/7-5.html Generating /home/paul/irregular.ninja/dist/html/7-5.html Generating /home/paul/irregular.ninja/dist/html/7-5.html Creating thumb /home/paul/irregular.ninja/dist/thumbs/DSCF0188.JPG Creating blur /home/paul/irregular.ninja/dist/blurs/DSCF0188.JPG Generating /home/paul/irregular.ninja/dist/html/page-7.html Generating /home/paul/irregular.ninja/dist/html/7-6.html Generating /home/paul/irregular.ninja/dist/html/7-6.html Generating /home/paul/irregular.ninja/dist/html/7-6.html Creating thumb /home/paul/irregular.ninja/dist/thumbs/P3500897-01.jpg Creating blur /home/paul/irregular.ninja/dist/blurs/P3500897-01.jpg . . . Generating /home/paul/irregular.ninja/dist/html/8-0.html Generating /home/paul/irregular.ninja/dist/html/8-41.html Generating /home/paul/irregular.ninja/dist/html/9-0.html Generating /home/paul/irregular.ninja/dist/html/9-41.html Generating /home/paul/irregular.ninja/dist/html/index.html Generating /home/paul/irregular.ninja/dist/.//index.html
% ls ./dist blurs html index.html photos thumbs
% rsync --delete -av ./dist/. admin@blowfish.buetow.org:/var/www/htdocs/irregular.ninja/
,_---~~~~~----._
_,,_,*^____ _____``*g*\"*,
____ _____ _ _ / __/ /' ^. / \ ^@q f
| _ \_ _|_ _(_) | @f | ((@| |@)) l 0 _/
| | | || |/ _` | | | \`/ \~____ / __ \_____/ \
| |_| || | (_| | | | | _l__l_ I
|____/ |_|\__,_|_|_| } [______] I
] | | | |
] ~ ~ |
| Let's tail those logs! |
| |
% dtail --servers serverlist.txt --grep INFO --files "/var/log/dserver/*.log"

% dtail --servers serverlist.txt --grep INFO "/var/log/dserver/*.log"
% dtail --servers serverlist.txt \
--files '/var/log/dserver/*.log' \
--query 'from STATS select sum($goroutines),sum($cgocalls),
last($time),max(lifetimeConnections)'

% dtail --servers serverlist.txt \
--files '/var/log/dserver/*.log' \
'from STATS select sum($goroutines),sum($cgocalls),
last($time),max(lifetimeConnections)'
% dtail --servers serverlist.txt \
--files '/var/log/dserver/*.log' \
--query 'from STATS select $hostname,max($goroutines),max($cgocalls),$loadavg,
lifetimeConnections group by $hostname order by max($cgocalls)'

% dtail --servers serverlist.txt \
--files '/var/log/dserver/*.log' \
--query 'from STATS select ... outfile append result.csv'
% dcat --servers serverlist.txt --files /etc/hostname

% dcat --servers serverlist.txt /etc/hostname
% dgrep --servers server1.example.org:2223 \
--files /etc/passwd \
--regex nologin

% dmap --servers serverlist.txt \
--files '/var/log/dserver/*.log' \
--query 'from STATS select $hostname,max($goroutines),max($cgocalls),$loadavg,
lifetimeConnections group by $hostname order by max($cgocalls)'

% dmap --files /var/log/dserver/dserver.log
--query 'from STATS select $hostname,max($goroutines),max($cgocalls),$loadavg,
lifetimeConnections group by $hostname order by max($cgocalls)'
% dmap 'from STATS select $hostname,max($goroutines),max($cgocalls),$loadavg,
lifetimeConnections group by $hostname order by max($cgocalls)' \
/var/log/dsever/dserver.log
% cat /var/log/dserver/dserver.log | \
dmap 'from STATS select $hostname,max($goroutines),max($cgocalls),$loadavg,
lifetimeConnections group by $hostname order by max($cgocalls)'
% cat example.csv name,lastname,age,profession Michael,Jordan,40,Basketball player Michael,Jackson,100,Singer Albert,Einstein,200,Physician % dmap --query 'select lastname,name where age > 40 logformat csv outfile result.csv' example.csv % cat result.csv lastname,name Jackson,Michael Einstein,Albert
% dtail /var/log/dserver/dserver.log
% dtail --logLevel trace /var/log/dserver/dserver.log
% dcat /etc/passwd
% dcat --plain /etc/passwd > /etc/test # Should show no differences. diff /etc/test /etc/passwd
% dgrep --regex ERROR --files /var/log/dserver/dsever.log
% dgrep --before 10 --after 10 --max 10 --grep ERROR /var/log/dserver/dsever.log
▓▓▓▓░░
DC on fire:
▓▓ ▓▓ ▓▓
░░ ░░ ▓▓▓▓ ██ ░░ ▓▓▓▓ ▓▓
▓▓░░░░ ░░ ▓▓▓▓ ▓▓░░ ▓▓▓▓
░░░░ ▓▓▓▓▓▓ ▓▓ ▓▓ ▓▓ ▓▓▓▓▓▓ ▓▓
▓▓░░ ▓▓▒▒▒▒▓▓▓▓ ▓▓ ▓▓▓▓ ▓▓▓▓▓▓ ▓▓▒▒▒▒▓▓▓▓ ▓▓▓▓
██▓▓ ▓▓▒▒░░▒▒▓▓ ▓▓██ ▓▓▓▓▓▓ ▓▓▒▒▓▓ ▓▓▒▒░░▒▒▓▓ ██▓▓▓▓
▓▓▓▓██ ▓▓▒▒░░░░▒▒▓▓ ▓▓▓▓ ▓▓▒▒▒▒▓▓ ▓▓▒▒░░▒▒▓▓██▓▓ ▓▓▒▒░░░░▒▒▓▓ ▓▓▒▒▒▒▓▓
▓▓▒▒▒▒▓▓▓▓▒▒░░▒▒▓▓▓▓▓▓▒▒▒▒▓▓ ▓▓▓▓░░▒▒▓▓ ▓▓▒▒░░▒▒▓▓▒▒▒▒▓▓ ▓▓▒▒░░▒▒▓▓▓▓▓▓▓▓░░▒▒▓▓
▒▒░░▒▒▓▓▓▓▒▒░░▒▒▓▓▓▓▒▒░░▒▒▓▓ ▓▓▒▒░░▒▒▓▓ ▓▓░░░░▒▒▒▒░░░░▒▒██████▒▒░░▒▒██▓▓▓▓▒▒░░▒▒▓▓██
░░░░▒▒▓▓▒▒░░▒▒▓▓▓▓▓▓▒▒░░▒▒▓▓██▒▒░░░░▒▒▓▓ ▓▓▒▒░░▒▒▓▓▒▒▒▒░░▒▒▓▓▓▓▒▒░░▒▒▓▓▓▓▓▓▒▒░░░░▒▒▓▓▓▓
░░░░▒▒▓▓▒▒░░░░▓▓██▒▒░░░░▒▒▓▓██▒▒░░░░▒▒██▓▓▓▓▒▒░░▒▒▓▓▓▓▒▒░░░░▒▒▓▓▒▒░░░░██▓▓▓▓▒▒░░░░▒▒████
▒▒░░▒▒▓▓▓▓░░░░▒▒▓▓▒▒▒▒░░░░▒▒▓▓▓▓▒▒░░░░▒▒▓▓▓▓▒▒░░░░▒▒▓▓▒▒░░▒▒▓▓▓▓▓▓░░░░▒▒▓▓▓▓▓▓▒▒░░░░▒▒▓▓
▒▒░░▒▒▓▓▒▒▒▒░░▒▒██▒▒▒▒░░▒▒▒▒██▒▒▒▒░░░░░░▒▒▓▓▒▒░░░░▒▒▒▒░░░░▒▒████▒▒▒▒░░▒▒██▓▓▒▒▒▒░░░░░░▒▒
░░░░░░▒▒░░░░░░░░▒▒▒▒▒▒░░░░▒▒▒▒▒▒░░░░░░░░▒▒▒▒░░░░░░▒▒▒▒░░░░░░▒▒▒▒░░░░░░░░▒▒▒▒▒▒░░░░░░░░▒▒
░░░░░░░░░░▒▒░░░░░░░░░░░░░░░░░░░░░░░░▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒░░░░░░░░░░░░░░░░░░
-=[ typewriters ]=- 1/98
.-------.
.-------. _|~~ ~~ |_
_|~~ ~~ |_ .-------. =(_|_______|_)
=(_|_______|_)= _|~~ ~~ |_ |:::::::::|
|:::::::::| =(_|_______|_) |:::::::[]|
|:::::::[]| |:::::::::| |o=======.|
|o=======.| |:::::::[]| `"""""""""`
jgs `"""""""""` |o=======.|
mod. by Paul Buetow `"""""""""`
```bash if [ -n "$foo" ]; then echo "$foo" fi ```
if [ -n "$foo" ]; then echo "$foo" fi
declare -xr MASTODON_URI='https://fosstodon.org/@snonux'
=> https://fosstodon.org/@snonux Me at Mastodon
<a href='https://fosstodon.org/@snonux' rel='me'>Me at Mastodon</a>
,.......... ..........,
,..,' '.' ',..,
,' ,' : ', ',
,' ,' : ', ',
,' ,' : ', ',
,' ,'............., : ,.............', ',
,' '............ '.' ............' ',
'''''''''''''''''';''';''''''''''''''''''
'''

_____________________________ ____________________________
/ \ / \
| _______________________ || ______________________ |
| / \ || / \ |
| | # Alerts with status c| || | # Unhandled alerts: | |
| | hanged: | || | | |
| | | || | CRITICAL: Check Pizza| |
| | OK->CRITICAL: Check Pi| || | : Late delivery | |
| | zza: Late delivery | || | | |
| | | || | WARNING: Check Thirst| |
| | | || | : OutofKombuchaExcept| |
| \_______________________/ || \______________________/ |
| /|\ GOGIOS MONITOR 1 _ || /|\ GOGIOS MONITOR 2 _ |
\_____________________________/ \____________________________/
!_________________________! !________________________!
------------------------------------------------
ASCII art was modified by Paul Buetow
The original can be found at
https://asciiart.website/index.php?art=objects/computers
Subject: GOGIOS Report [C:2 W:0 U:0 OK:51] This is the recent Gogios report! # Alerts with status changed: OK->CRITICAL: Check ICMP4 vulcan.buetow.org: Check command timed out OK->CRITICAL: Check ICMP6 vulcan.buetow.org: Check command timed out # Unhandled alerts: CRITICAL: Check ICMP4 vulcan.buetow.org: Check command timed out CRITICAL: Check ICMP6 vulcan.buetow.org: Check command timed out Have a nice day!
git clone https://codeberg.org/snonux/gogios.git cd gogios go build -o gogios cmd/gogios/main.go doas cp gogios /usr/local/bin/gogios doas chmod 755 /usr/local/bin/gogios
export GOOS=openbsd export GOARCH=amd64 go build -o gogios cmd/gogios/main.go
doas adduser -group _gogios -batch _gogios doas usermod -d /var/run/gogios _gogios doas mkdir -p /var/run/gogios doas chown _gogios:_gogios /var/run/gogios doas chmod 750 /var/run/gogios
doas pkg_add monitoring-plugins doas pkg_add nrpe # If you want to execute checks remotely via NRPE.
echo 'This is a test email from OpenBSD.' | mail -s 'Test Email' your-email@example.com
{
"EmailTo": "paul@dev.buetow.org",
"EmailFrom": "gogios@buetow.org",
"CheckTimeoutS": 10,
"CheckConcurrency": 2,
"StateDir": "/var/run/gogios",
"Checks": {
"Check ICMP4 www.foo.zone": {
"Plugin": "/usr/local/libexec/nagios/check_ping",
"Args": [ "-H", "www.foo.zone", "-4", "-w", "50,10%", "-c", "100,15%" ],
"Retries": 3,
"RetryInterval": 10
},
"Check ICMP6 www.foo.zone": {
"Plugin": "/usr/local/libexec/nagios/check_ping",
"Args": [ "-H", "www.foo.zone", "-6", "-w", "50,10%", "-c", "100,15%" ],
"Retries": 3,
"RetryInterval": 10
},
"www.foo.zone HTTP IPv4": {
"Plugin": "/usr/local/libexec/nagios/check_http",
"Args": ["www.foo.zone", "-4"],
"DependsOn": ["Check ICMP4 www.foo.zone"]
},
"www.foo.zone HTTP IPv6": {
"Plugin": "/usr/local/libexec/nagios/check_http",
"Args": ["www.foo.zone", "-6"],
"DependsOn": ["Check ICMP6 www.foo.zone"]
}
"Check NRPE Disk Usage foo.zone": {
"Plugin": "/usr/local/libexec/nagios/check_nrpe",
"Args": ["-H", "foo.zone", "-c", "check_disk", "-p", "5666", "-4"]
}
}
}
doas -u _gogios /usr/local/bin/gogios -cfg /etc/gogios.json
*/5 8-22 * * * /usr/local/bin/gogios -cfg /etc/gogios.json 0 7 * * * /usr/local/bin/gogios -renotify -cfg /etc/gogios.json
,.......... ..........,
,..,' '.' ',..,
,' ,' : ', ',
,' ,' : ', ',
,' ,' : ', ',
,' ,'............., : ,.............', ',
,' '............ '.' ............' ',
'''''''''''''''''';''';''''''''''''''''''
'''
+-----+-----------------+-----------------------------+ | Pos | Host | Lifespan | +-----+-----------------+-----------------------------+ | 1. | dionysus | 8 years, 6 months, 17 days | | 2. | uranus | 7 years, 2 months, 16 days | | 3. | alphacentauri | 6 years, 9 months, 13 days | | 4. | *vulcan | 4 years, 5 months, 6 days | | 5. | sun | 3 years, 10 months, 2 days | | 6. | uugrn | 3 years, 5 months, 5 days | | 7. | deltavega | 3 years, 1 months, 21 days | | 8. | pluto | 2 years, 10 months, 30 days | | 9. | tauceti | 2 years, 3 months, 22 days | | 10. | callisto | 2 years, 3 months, 13 days | +-----+-----------------+-----------------------------+
$ raku guprecords.raku --stats=dir=$HOME/git/uprecords/stats --all
Top 20 Uptime's by Host +-----+-----------------+-----------------------------+ | Pos | Host | Uptime | +-----+-----------------+-----------------------------+ | 1. | *vulcan | 4 years, 5 months, 6 days | | 2. | uranus | 3 years, 11 months, 21 days | | 3. | sun | 3 years, 9 months, 26 days | | 4. | uugrn | 3 years, 5 months, 5 days | | 5. | deltavega | 3 years, 1 months, 21 days | | 6. | pluto | 2 years, 10 months, 29 days | | 7. | tauceti | 2 years, 3 months, 19 days | | 8. | tauceti-f | 1 years, 9 months, 18 days | | 9. | *ultramega15289 | 1 years, 8 months, 17 days | | 10. | *earth | 1 years, 5 months, 22 days | | 11. | *blowfish | 1 years, 4 months, 20 days | | 12. | ultramega8477 | 1 years, 3 months, 25 days | | 13. | host0 | 1 years, 3 months, 9 days | | 14. | tauceti-e | 1 years, 2 months, 20 days | | 15. | makemake | 1 years, 1 months, 6 days | | 16. | callisto | 0 years, 10 months, 31 days | | 17. | alphacentauri | 0 years, 10 months, 28 days | | 18. | london | 0 years, 9 months, 16 days | | 19. | twofish | 0 years, 8 months, 31 days | | 20. | *fishfinger | 0 years, 8 months, 17 days | +-----+-----------------+-----------------------------+
# Uptime | System Boot up
----------------------------+---------------------------------------------------
1 545 days, 17:58:15 | Linux 3.10.0-1160.15.2.e Sun Jul 25 19:32:25 2021
2 279 days, 10:12:14 | Linux 3.10.0-957.21.3.el Sun Jun 30 12:43:41 2019
3 161 days, 06:08:43 | Linux 3.10.0-1160.15.2.e Sun Feb 14 11:05:38 2021
4 107 days, 01:26:35 | Linux 3.10.0-957.1.3.el7 Thu Dec 20 09:29:13 2018
5 96 days, 21:13:49 | Linux 3.10.0-1127.13.1.e Sat Jul 25 17:56:22 2020
-> 6 89 days, 23:05:32 | Linux 3.10.0-1160.81.1.e Sun Jan 22 12:39:36 2023
7 63 days, 18:30:45 | Linux 3.10.0-957.10.1.el Sat Apr 27 18:12:43 2019
8 63 days, 06:53:33 | Linux 3.10.0-1127.8.2.el Sat May 23 10:41:08 2020
9 48 days, 11:44:49 | Linux 3.10.0-1062.18.1.e Sat Apr 4 22:56:07 2020
10 42 days, 08:00:13 | Linux 3.10.0-1127.19.1.e Sat Nov 7 11:47:33 2020
11 36 days, 22:57:19 | Linux 3.10.0-1160.6.1.el Sat Dec 19 19:47:57 2020
12 21 days, 06:16:28 | Linux 3.10.0-957.10.1.el Sat Apr 6 11:56:01 2019
13 12 days, 20:11:53 | Linux 3.10.0-1160.11.1.e Mon Jan 25 18:45:27 2021
14 7 days, 21:29:18 | Linux 3.10.0-1127.13.1.e Fri Oct 30 14:18:04 2020
15 6 days, 20:07:18 | Linux 3.10.0-1160.15.2.e Sun Feb 7 14:57:35 2021
16 1 day , 21:46:41 | Linux 3.10.0-957.1.3.el7 Tue Dec 18 11:42:19 2018
17 0 days, 01:25:57 | Linux 3.10.0-957.1.3.el7 Tue Dec 18 10:16:08 2018
18 0 days, 00:42:34 | Linux 3.10.0-1160.15.2.e Sun Jul 25 18:49:38 2021
19 0 days, 00:08:32 | Linux 3.10.0-1160.81.1.e Sun Jan 22 12:30:52 2023
----------------------------+---------------------------------------------------
1up in 6 days, 22:08:18 | at Sat Apr 29 10:53:25 2023
no1 in 455 days, 18:52:44 | at Sun Jul 21 07:37:51 2024
up 1586 days, 00:20:28 | since Tue Dec 18 10:16:08 2018
down 0 days, 01:08:32 | since Tue Dec 18 10:16:08 2018
%up 99.997 | since Tue Dec 18 10:16:08 2018
,.......... ..........,
,..,' '.' ',..,
,' ,' : ', ',
,' ,' : ', ',
,' ,' : ', ',
,' ,'............., : ,.............', ',
,' '............ '.' ............' ',
'''''''''''''''''';''';''''''''''''''''''
'''
-=[ typewriters ]=- 1/98
.-------.
_|~~ ~~ |_ .-------.
=(_|_______|_)= _|~~ ~~ |_
|:::::::::| =(_|_______|_)
|:::::::[]| |:::::::::|
|o=======.| |:::::::[]|
jgs `"""""""""` |o=======.|
mod. by Paul Buetow `"""""""""`
# Hello world
<< echo "> This site was generated at $(date --iso-8601=seconds) by \`Gemtexter\`"
Welcome to this capsule!
<<<
for i in {1..10}; do
echo Multiline template line $i
done
>>>
# Hello world > This site was generated at 2023-03-15T19:07:59+02:00 by `Gemtexter` Welcome to this capsule! Multiline template line 1 Multiline template line 2 Multiline template line 3 Multiline template line 4 Multiline template line 5 Multiline template line 6 Multiline template line 7 Multiline template line 8 Multiline template line 9 Multiline template line 10
See more entries about DTail and Golang: << template::inline::index dtail golang Blablabla...
See more entries about DTail and Golang: => ./2022-10-30-installing-dtail-on-openbsd.gmi 2022-10-30 Installing DTail on OpenBSD => ./2022-04-22-programming-golang.gmi 2022-04-22 The Golang Programming language => ./2022-03-06-the-release-of-dtail-4.0.0.gmi 2022-03-06 The release of DTail 4.0.0 => ./2021-04-22-dtail-the-distributed-log-tail-program.gmi 2021-04-22 DTail - The distributed log tail program (You are currently reading this) Blablabla...
declare -xr PRE_GENERATE_HOOK=./pre_generate_hook.sh declare -xr POST_PUBLISH_HOOK=./post_publish_hook.sh
% cat gemfeed/2023-02-26-title-here.gmi # Title here The remaining content of the Gemtext file...
% cat gemfeed/2023-02-26-title-here.gmi # Title here > Published at 2023-02-26T21:43:51+01:00 The remaining content of the Gemtext file...
,.......... ..........,
,..,' '.' ',..,
,' ,' : ', ',
,' ,' : ', ',
,' ,' : ', ',
,' ,'............., : ,.............', ',
,' '............ '.' ............' ',
'''''''''''''''''';''';''''''''''''''''''
'''
|\ "Music should be heard not only with the ears, but also the soul."
|---|--\-----------------------|-----------------------------------------|
| | |\ | |@ |\ |
|---|---|--\-------------------|-------------/|----|------|--\----|------|
| @| | |\ |O | 3 / | |@ | | |
|---|--@|---|--\--------|------|---------/----|----|------|-------|------|
| @| @| \ |O | / | | |@ @| @|. |
|-----------|-----|-----|------|-----/---|---@|----|--------------|------|
| @| | |O | | | | @|. |
|-----------|----@|-----|------|----|---@|------------------------|------|
@| | | Larry Komro @|.
-@- [kom...@uwec.edu]
Art by Joan Stark
_.===========================._
.'` .- - __- - - -- --__--- -. `'.
__ / ,'` _|--|_________|--|_ `'. \
/'--| ; _.'\ | ' ' | /'._ ; |
// | |_.-' .-'.' ___ '.'-. '-._| |
(\) \"` _.-` / .-'`_ `'-. \ `-._ `"/
(\) `-' | .' .-'" "'-. '. | `-`
(\) | / .'(3)(2)(1)'. \ |
(\) | / / (4) .-. \ \ |
(\) | | |(5) ( )'==,J | |
(\) | \ \ (6) '-' (0) / / |
(\) | \ '.(7)(8)(9).' / |
(\) ___| '. '-.._..-' .' |
(\) /.--| '-._____.-' |
(\) (\) |\_ _ __ _ __ __/|
(\) (\) | |
(\)_._._.__(\) | |
(\\\\jgs\\\) '.___________________.'
'-'-'-'--'


_/ \ _(\(o
/ \ / _ ^^^o
/ ! \/ ! '!!!v'
! ! \ _' ( \____
! . \ _!\ \===^\)
Art by \ \_! / __!
Gunnar Z. \! / \ <--- Emacs is a giant dragon
(\_ _/ _\ )
\ ^^--^^ __-^ /(__
^^----^^ "^--v'
" Clipboard vnoremap ,y !pbcopy<CR>ugv vnoremap ,i !pbpaste<CR> nmap ,i !wpbpaste<CR>
,_---~~~~~----._
_,,_,*^____ _____``*g*\"*,
/ __/ /' ^. / \ ^@q f
@f | | | | 0 _/
\`/ \~__((@/ __ \__((@/ \
| _l__l_ I <--- The Go Gopher
} [______] I
] | | | |
] ~ ~ |
| |
| |
| | A ;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~~~,--,-/ \---,-/|~~,~~~~~~~~~~~~~~~~~~~~~~~~~~~
_|\,'. /| /| `/|-.
\`.' /| , `;.
,'\ A A A A _ /| `.;
,/ _ A _ / _ /| ;
/\ / \ , , A / / `/|
/_| | _ \ , , ,/ \
// | |/ `.\ ,- , , ,/ ,/ \/
/ @| |@ / /' \ \ , > /| ,--.
|\_/ \_/ / | | , ,/ \ ./' __:..
| __ __ | | | .--. , > > |-' / `
,/| / ' \ | | | \ , | /
/ |<--.__,->| | | . `. > > / (
/_,' \\ ^ / \ / / `. >-- /^\ |
\\___/ \ / / \__' \ \ \/ \ |
`. |/ , , /`\ \ )
\ ' |/ , V \ / `-\
OpenBSD Puffy ---> `|/ ' V V \ \.' \_
'`-. V V \./'\
`|/-. \ / \ /,---`\ kat
/ `._____V_____V'
' '
$ doas pkg_add git go gmake
$ mkdir git $ cd git $ git clone https://github.com/mimecast/dtail $ cd dtail $ gmake
$ ./dtail --version DTail 4.1.0 Protocol 4.1 Have a lot of fun! $ file dtail dtail: ELF 64-bit LSB executable, x86-64, version 1
$ doas pkg_delete git go gmake
$ for bin in dserver dcat dgrep dmap dtail dtailhealth; do doas cp -p $bin /usr/local/bin/$bin doas chown root:wheel /usr/local/bin/$bin done
$ doas adduser -class nologin -group _dserver -batch _dserver $ doas usermod -d /var/run/dserver/ _dserver
$ cat <<'END' | doas tee /etc/rc.d/dserver
#!/bin/ksh
daemon="/usr/local/bin/dserver"
daemon_flags="-cfg /etc/dserver/dtail.json"
daemon_user="_dserver"
. /etc/rc.d/rc.subr
rc_reload=NO
rc_pre() {
install -d -o _dserver /var/log/dserver
install -d -o _dserver /var/run/dserver/cache
}
rc_cmd $1 &
END
$ doas chmod 755 /etc/rc.d/dserver
desc 'Setup DTail';
task 'dtail', group => 'frontends',
sub {
my $restart = FALSE;
file '/etc/rc.d/dserver':
content => template('./etc/rc.d/dserver.tpl'),
owner => 'root',
group => 'wheel',
mode => '755',
on_change => sub { $restart = TRUE };
.
.
.
.
service 'dserver' => 'restart' if $restart;
service 'dserver', ensure => 'started';
};
$ doas mkdir /etc/dserver
$ curl https://raw.githubusercontent.com/mimecast/dtail/master/examples/dtail.json.examples |
doas tee /etc/dserver/dtail.json
"Common": {
"LogDir": "/var/log/dserver",
"Logger": "Fout",
"LogRotation": "Daily",
"CacheDir": "cache",
"SSHPort": 2222,
"LogLevel": "Info"
}
file '/etc/dserver',
ensure => 'directory';
file '/etc/dserver/dtail.json',
content => template('./etc/dserver/dtail.json.tpl'),
owner => 'root',
group => 'wheel',
mode => '755',
on_change => sub { $restart = TRUE };
$ cat <<'END' | doas tee /usr/local/bin/dserver-update-key-cache.sh
#!/bin/ksh
CACHEDIR=/var/run/dserver/cache
DSERVER_USER=_dserver
DSERVER_GROUP=_dserver
echo 'Updating SSH key cache'
ls /home/ | while read remoteuser; do
keysfile=/home/$remoteuser/.ssh/authorized_keys
if [ -f $keysfile ]; then
cachefile=$CACHEDIR/$remoteuser.authorized_keys
echo "Caching $keysfile -> $cachefile"
cp $keysfile $cachefile
chown $DSERVER_USER:$DSERVER_GROUP $cachefile
chmod 600 $cachefile
fi
done
# Cleanup obsolete public SSH keys
find $CACHEDIR -name \*.authorized_keys -type f |
while read cachefile; do
remoteuser=$(basename $cachefile | cut -d. -f1)
keysfile=/home/$remoteuser/.ssh/authorized_keys
if [ ! -f $keysfile ]; then
echo 'Deleting obsolete cache file $cachefile'
rm $cachefile
fi
done
echo 'All set...'
END
$ doas chmod 500 /usr/local/bin/dserver-update-key-cache.sh
$ echo /usr/local/bin/dserver-update-key-cache.sh | doas tee -a /etc/daily.local /usr/local/bin/dserver-update-key-cache.sh
file '/usr/local/bin/dserver-update-key-cache.sh',
content => template('./scripts/dserver-update-key-cache.sh.tpl'),
owner => 'root',
group => 'wheel',
mode => '500';
append_if_no_such_line '/etc/daily.local', '/usr/local/bin/dserver-update-key-cache.sh';
$ sudo rcctl enable dserver $ sudo rcctl start dserver $ tail -f /var/log/dserver/*.log INFO|1022-090634|Starting scheduled job runner after 2s INFO|1022-090634|Starting continuous job runner after 2s INFO|1022-090644|24204|stats.go:53|2|11|7|||MAPREDUCE:STATS|currentConnections=0|lifetimeConnections=0 INFO|1022-090654|24204|stats.go:53|2|11|7|||MAPREDUCE:STATS|currentConnections=0|lifetimeConnections=0 INFO|1022-090719|Starting server|DTail 4.1.0 Protocol 4.1 Have a lot of fun! INFO|1022-090719|Generating private server RSA host key INFO|1022-090719|Starting server INFO|1022-090719|Binding server|0.0.0.0:2222 INFO|1022-090719|Starting scheduled job runner after 2s INFO|1022-090719|Starting continuous job runner after 2s INFO|1022-090729|86050|stats.go:53|2|11|7|||MAPREDUCE:STATS|currentConnections=0|lifetimeConnections=0 INFO|1022-090739|86050|stats.go:53|2|11|7|||MAPREDUCE:STATS|currentConnections=0|lifetimeConnect . . . Ctr+C
$ doas /usr/local/bin/dserver-update-key-cache.sh Updating SSH key cache Caching /home/_dserver/.ssh/authorized_keys -> /var/cache/dserver/_dserver.authorized_keys Caching /home/admin/.ssh/authorized_keys -> /var/cache/dserver/admin.authorized_keys Caching /home/failunderd/.ssh/authorized_keys -> /var/cache/dserver/failunderd.authorized_keys Caching /home/git/.ssh/authorized_keys -> /var/cache/dserver/git.authorized_keys Caching /home/paul/.ssh/authorized_keys -> /var/cache/dserver/paul.authorized_keys Caching /home/rex/.ssh/authorized_keys -> /var/cache/dserver/rex.authorized_keys All set...
❯ ./dgrep -user rex -servers blowfish.buetow.org,fishfinger.buetow.org --regex local /etc/fstab
CLIENT|earth|WARN|Encountered unknown host|{blowfish.buetow.org:2222 0xc0000a00f0 0xc0000a61e0 [blowfish.buetow.org]:2222 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9ZnF/LAk14SgqCzk38yENVTNfqibcluMTuKx1u53cKSp2xwHWzy0Ni5smFPpJDIQQljQEJl14ZdXvhhjp1kKHxJ79ubqRtIXBlC0PhlnP8Kd+mVLLHYpH9VO4rnaSfHE1kBjWkI7U6lLc6ks4flgAgGTS5Bb7pLAjwdWg794GWcnRh6kSUEQd3SftANqQLgCunDcP2Vc4KR9R78zBmEzXH/OPzl/ANgNA6wWO2OoKKy2VrjwVAab6FW15h3Lr6rYIw3KztpG+UMmEj5ReexIjXi/jUptdnUFWspvAmzIl6kwzzF8ExVyT9D75JRuHvmxXKKjyJRxqb8UnSh2JD4JN [23.88.35.144]:2222 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9ZnF/LAk14SgqCzk38yENVTNfqibcluMTuKx1u53cKSp2xwHWzy0Ni5smFPpJDIQQljQEJl14ZdXvhhjp1kKHxJ79ubqRtIXBlC0PhlnP8Kd+mVLLHYpH9VO4rnaSfHE1kBjWkI7U6lLc6ks4flgAgGTS5Bb7pLAjwdWg794GWcnRh6kSUEQd3SftANqQLgCunDcP2Vc4KR9R78zBmEzXH/OPzl/ANgNA6wWO2OoKKy2VrjwVAab6FW15h3Lr6rYIw3KztpG+UMmEj5ReexIjXi/jUptdnUFWspvAmzIl6kwzzF8ExVyT9D75JRuHvmxXKKjyJRxqb8UnSh2JD4JN 0xc0000a2180}
CLIENT|earth|WARN|Encountered unknown host|{fishfinger.buetow.org:2222 0xc0000a0150 0xc000460110 [fishfinger.buetow.org]:2222 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDNiikdL7+tWSN0rCaw1tOd9aQgeUFgb830V9ejkyJ5h93PKLCWZSMMCtiabc1aUeUZR//rZjcPHFLuLq/YC+Y3naYtGd6j8qVrcfG8jy3gCbs4tV9SZ9qd5E24mtYqYdGlee6JN6kEWhJxFkEwPfNlG+YAr3KC8lvEAE2JdWvaZavqsqMvHZtAX3b25WCBf2HGkyLZ+d9cnimRUOt+/+353BQFCEct/2mhMVlkr4I23CY6Tsufx0vtxx25nbFdZias6wmhxaE9p3LiWXygPWGU5iZ4RSQSImQz4zyOc9rnJeP1rwGk0OWDJhdKNXuf0kIPdzMfwxv2otgY32/DJj6L [46.23.94.99]:2222 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDNiikdL7+tWSN0rCaw1tOd9aQgeUFgb830V9ejkyJ5h93PKLCWZSMMCtiabc1aUeUZR//rZjcPHFLuLq/YC+Y3naYtGd6j8qVrcfG8jy3gCbs4tV9SZ9qd5E24mtYqYdGlee6JN6kEWhJxFkEwPfNlG+YAr3KC8lvEAE2JdWvaZavqsqMvHZtAX3b25WCBf2HGkyLZ+d9cnimRUOt+/+353BQFCEct/2mhMVlkr4I23CY6Tsufx0vtxx25nbFdZias6wmhxaE9p3LiWXygPWGU5iZ4RSQSImQz4zyOc9rnJeP1rwGk0OWDJhdKNXuf0kIPdzMfwxv2otgY32/DJj6L 0xc0000a2240}
Encountered 2 unknown hosts: 'blowfish.buetow.org:2222,fishfinger.buetow.org:2222'
Do you want to trust these hosts?? (y=yes,a=all,n=no,d=details): a
CLIENT|earth|INFO|STATS:STATS|cgocalls=11|cpu=8|connected=2|servers=2|connected%=100|new=2|throttle=0|goroutines=19
CLIENT|earth|INFO|Added hosts to known hosts file|/home/paul/.ssh/known_hosts
REMOTE|blowfish|100|7|fstab|31bfd9d9a6788844.h /usr/local ffs rw,wxallowed,nodev 1 2
REMOTE|fishfinger|100|7|fstab|093f510ec5c0f512.h /usr/local ffs rw,wxallowed,nodev 1 2
❯ ./dgrep -user rex -servers blowfish.buetow.org,fishfinger.buetow.org --regex local /etc/fstab REMOTE|blowfish|100|7|fstab|31bfd9d9a6788844.h /usr/local ffs rw,wxallowed,nodev 1 2 REMOTE|fishfinger|100|7|fstab|093f510ec5c0f512.h /usr/local ffs rw,wxallowed,nodev 1 2
z
z
Z
.--. Z Z
/ _(c\ .-. __
| / / '-; \'-'` `\______
\_\/'/ __/ ) / ) | \--,
| \`""`__-/ .'--/ /--------\ \
\\` ///-\/ / /---;-. '-'
jgs (________\ \
'-'
-=[ typewriter ]=- 1/98
.-------.
_|~~ ~~ |_
=(_|_______|_)=
|:::::::::|
|:::::::[]|
|o=======.|
jgs `"""""""""`
check_dependencies () {
# At least, Bash 5 is required
local -i required_version=5
IFS=. read -ra version <<< "$BASH_VERSION"
if [ "${version[0]}" -lt $required_version ]; then
log ERROR "ERROR, \"bash\" must be at least at major version $required_version!"
exit 2
fi
# These must be the GNU versions of the commands
for tool in $DATE $SED $GREP; do
if ! $tool --version | grep -q GNU; then
log ERROR "ERROR, \"$tool\" command is not the GNU version, please install!"
exit 2
fi
done
}
./gemtexter --generate '.*hello.*'
/ _ \
The Hebern Machine \ ." ". /
___ / \
.."" "".. | O |
/ \ | |
/ \ | |
---------------------------------
_/ o (O) o _ |
_/ ." ". |
I/ _________________/ \ |
_/I ." | |
===== / I / / |
===== | | | \ | _________________." |
===== | | | | | / \ / _|_|__|_|_ __ |
| | | | | | | \ "._." / o o \ ." ". |
| --| --| -| / \ _/ / \ |
\____\____\__| \ ______ | / | | |
-------- --- / | | |
( ) (O) / \ / |
----------------------- ".__." |
_|__________________________________________|_
/ \
/________________________________________________\
ASCII Art by John Savard
#
# $OpenBSD: acme-client.conf,v 1.4 2020/09/17 09:13:06 florian Exp $
#
authority letsencrypt {
api url "https://acme-v02.api.letsencrypt.org/directory"
account key "/etc/acme/letsencrypt-privkey.pem"
}
authority letsencrypt-staging {
api url "https://acme-staging-v02.api.letsencrypt.org/directory"
account key "/etc/acme/letsencrypt-staging-privkey.pem"
}
authority buypass {
api url "https://api.buypass.com/acme/directory"
account key "/etc/acme/buypass-privkey.pem"
contact "mailto:me@example.com"
}
authority buypass-test {
api url "https://api.test4.buypass.no/acme/directory"
account key "/etc/acme/buypass-test-privkey.pem"
contact "mailto:me@example.com"
}
domain buetow.org {
alternative names { www.buetow.org paul.buetow.org }
domain key "/etc/ssl/private/buetow.org.key"
domain full chain certificate "/etc/ssl/buetow.org.fullchain.pem"
sign with letsencrypt
}
domain dtail.dev {
alternative names { www.dtail.dev }
domain key "/etc/ssl/private/dtail.dev.key"
domain full chain certificate "/etc/ssl/dtail.dev.fullchain.pem"
sign with letsencrypt
}
domain foo.zone {
alternative names { www.foo.zone }
domain key "/etc/ssl/private/foo.zone.key"
domain full chain certificate "/etc/ssl/foo.zone.fullchain.pem"
sign with letsencrypt
}
domain irregular.ninja {
alternative names { www.irregular.ninja }
domain key "/etc/ssl/private/irregular.ninja.key"
domain full chain certificate "/etc/ssl/irregular.ninja.fullchain.pem"
sign with letsencrypt
}
domain snonux.land {
alternative names { www.snonux.land }
domain key "/etc/ssl/private/snonux.land.key"
domain full chain certificate "/etc/ssl/snonux.land.fullchain.pem"
sign with letsencrypt
}
server "foo.zone" {
listen on * port 80
location "/.well-known/acme-challenge/*" {
root "/acme"
request strip 2
}
location * {
block return 302 "https://$HTTP_HOST$REQUEST_URI"
}
}
server "foo.zone" {
listen on * tls port 443
tls {
certificate "/etc/ssl/foo.zone.fullchain.pem"
key "/etc/ssl/private/foo.zone.key"
}
location * {
root "/htdocs/gemtexter/foo.zone"
directory auto index
}
}
#!/bin/sh
function handle_cert {
host=$1
# Create symlink, so that relayd also can read it.
crt_path=/etc/ssl/$host
if [ -e $crt_path.crt ]; then
rm $crt_path.crt
fi
ln -s $crt_path.fullchain.pem $crt_path.crt
# Requesting and renewing certificate.
/usr/sbin/acme-client -v $host
}
has_update=no
handle_cert www.buetow.org
if [ $? -eq 0 ]; then
has_update=yes
fi
handle_cert www.paul.buetow.org
if [ $? -eq 0 ]; then
has_update=yes
fi
handle_cert www.tmp.buetow.org
if [ $? -eq 0 ]; then
has_update=yes
fi
handle_cert www.dtail.dev
if [ $? -eq 0 ]; then
has_update=yes
fi
handle_cert www.foo.zone
if [ $? -eq 0 ]; then
has_update=yes
fi
handle_cert www.irregular.ninja
if [ $? -eq 0 ]; then
has_update=yes
fi
handle_cert www.snonux.land
if [ $? -eq 0 ]; then
has_update=yes
fi
# Pick up the new certs.
if [ $has_update = yes ]; then
/usr/sbin/rcctl reload httpd
/usr/sbin/rcctl reload relayd
/usr/sbin/rcctl restart smtpd
fi
/usr/local/bin/acme.sh
Running daily.local: acme-client: /etc/ssl/buetow.org.fullchain.pem: certificate valid: 80 days left acme-client: /etc/ssl/paul.buetow.org.fullchain.pem: certificate valid: 80 days left acme-client: /etc/ssl/tmp.buetow.org.fullchain.pem: certificate valid: 80 days left acme-client: /etc/ssl/dtail.dev.fullchain.pem: certificate valid: 80 days left acme-client: /etc/ssl/foo.zone.fullchain.pem: certificate valid: 80 days left acme-client: /etc/ssl/irregular.ninja.fullchain.pem: certificate valid: 80 days left acme-client: /etc/ssl/snonux.land.fullchain.pem: certificate valid: 79 days left
our @acme_hosts = qw/buetow.org paul.buetow.org tmp.buetow.org dtail.dev foo.zone irregular.ninja snonux.land/;
group frontends => 'blowfish.buetow.org', 'twofish.buetow.org';
desc 'Configure ACME client';
task 'acme', group => 'frontends',
sub {
file '/etc/acme-client.conf',
content => template('./etc/acme-client.conf.tpl',
acme_hosts => \@acme_hosts,
is_primary => $is_primary),
owner => 'root',
group => 'wheel',
mode => '644';
file '/usr/local/bin/acme.sh',
content => template('./scripts/acme.sh.tpl',
acme_hosts => \@acme_hosts,
is_primary => $is_primary),
owner => 'root',
group => 'wheel',
mode => '744';
file '/etc/daily.local',
ensure => 'present',
owner => 'root',
group => 'wheel',
mode => '644';
append_if_no_such_line '/etc/daily.local', '/usr/local/bin/acme.sh';
};
desc 'Invoke ACME client';
task 'acme_invoke', group => 'frontends',
sub {
say run '/usr/local/bin/acme.sh';
};
# Bootstrapping the FQDN based on the server IP as the hostname and domain
# facts aren't set yet due to the myname file in the first place.
our $fqdns = sub {
my $ipv4 = shift;
return 'blowfish.buetow.org' if $ipv4 eq '23.88.35.144';
return 'twofish.buetow.org' if $ipv4 eq '108.160.134.135';
Rex::Logger::info("Unable to determine hostname for $ipv4", 'error');
return 'HOSTNAME-UNKNOWN.buetow.org';
};
# To determine whether the server is the primary or the secondary.
our $is_primary = sub {
my $ipv4 = shift;
$fqdns->($ipv4) eq 'blowfish.buetow.org';
};
#
# $OpenBSD: acme-client.conf,v 1.4 2020/09/17 09:13:06 florian Exp $
#
authority letsencrypt {
api url "https://acme-v02.api.letsencrypt.org/directory"
account key "/etc/acme/letsencrypt-privkey.pem"
}
authority letsencrypt-staging {
api url "https://acme-staging-v02.api.letsencrypt.org/directory"
account key "/etc/acme/letsencrypt-staging-privkey.pem"
}
authority buypass {
api url "https://api.buypass.com/acme/directory"
account key "/etc/acme/buypass-privkey.pem"
contact "mailto:me@example.com"
}
authority buypass-test {
api url "https://api.test4.buypass.no/acme/directory"
account key "/etc/acme/buypass-test-privkey.pem"
contact "mailto:me@example.com"
}
<%
our $primary = $is_primary->($vio0_ip);
our $prefix = $primary ? '' : 'www.';
%>
<% for my $host (@$acme_hosts) { %>
domain <%= $prefix.$host %> {
domain key "/etc/ssl/private/<%= $prefix.$host %>.key"
domain full chain certificate "/etc/ssl/<%= $prefix.$host %>.fullchain.pem"
sign with letsencrypt
}
<% } %>
#!/bin/sh
<%
our $primary = $is_primary->($vio0_ip);
our $prefix = $primary ? '' : 'www.';
-%>
function handle_cert {
host=$1
# Create symlink, so that relayd also can read it.
crt_path=/etc/ssl/$host
if [ -e $crt_path.crt ]; then
rm $crt_path.crt
fi
ln -s $crt_path.fullchain.pem $crt_path.crt
# Requesting and renewing certificate.
/usr/sbin/acme-client -v $host
}
has_update=no
<% for my $host (@$acme_hosts) { -%>
handle_cert <%= $prefix.$host %>
if [ $? -eq 0 ]; then
has_update=yes
fi
<% } -%>
# Pick up the new certs.
if [ $has_update = yes ]; then
/usr/sbin/rcctl reload httpd
/usr/sbin/rcctl reload relayd
/usr/sbin/rcctl restart smtpd
fi
desc 'Setup httpd';
task 'httpd', group => 'frontends',
sub {
append_if_no_such_line '/etc/rc.conf.local', 'httpd_flags=';
file '/etc/httpd.conf',
content => template('./etc/httpd.conf.tpl',
acme_hosts => \@acme_hosts,
is_primary => $is_primary),
owner => 'root',
group => 'wheel',
mode => '644',
on_change => sub { service 'httpd' => 'restart' };
service 'httpd', ensure => 'started';
};
desc 'Setup relayd';
task 'relayd', group => 'frontends',
sub {
append_if_no_such_line '/etc/rc.conf.local', 'relayd_flags=';
file '/etc/relayd.conf',
content => template('./etc/relayd.conf.tpl',
ipv6address => $ipv6address,
is_primary => $is_primary),
owner => 'root',
group => 'wheel',
mode => '600',
on_change => sub { service 'relayd' => 'restart' };
service 'relayd', ensure => 'started';
};
desc 'Setup OpenSMTPD';
task 'smtpd', group => 'frontends',
sub {
Rex::Logger::info('Dealing with mail aliases');
file '/etc/mail/aliases',
source => './etc/mail/aliases',
owner => 'root',
group => 'wheel',
mode => '644',
on_change => sub { say run 'newaliases' };
Rex::Logger::info('Dealing with mail virtual domains');
file '/etc/mail/virtualdomains',
source => './etc/mail/virtualdomains',
owner => 'root',
group => 'wheel',
mode => '644',
on_change => sub { service 'smtpd' => 'restart' };
Rex::Logger::info('Dealing with mail virtual users');
file '/etc/mail/virtualusers',
source => './etc/mail/virtualusers',
owner => 'root',
group => 'wheel',
mode => '644',
on_change => sub { service 'smtpd' => 'restart' };
Rex::Logger::info('Dealing with smtpd.conf');
file '/etc/mail/smtpd.conf',
content => template('./etc/mail/smtpd.conf.tpl',
is_primary => $is_primary),
owner => 'root',
group => 'wheel',
mode => '644',
on_change => sub { service 'smtpd' => 'restart' };
service 'smtpd', ensure => 'started';
};
<%
our $primary = $is_primary->($vio0_ip);
our $prefix = $primary ? '' : 'www.';
%>
# Plain HTTP for ACME and HTTPS redirect
<% for my $host (@$acme_hosts) { %>
server "<%= $prefix.$host %>" {
listen on * port 80
location "/.well-known/acme-challenge/*" {
root "/acme"
request strip 2
}
location * {
block return 302 "https://$HTTP_HOST$REQUEST_URI"
}
}
<% } %>
# Gemtexter hosts
<% for my $host (qw/foo.zone snonux.land/) { %>
server "<%= $prefix.$host %>" {
listen on * tls port 443
tls {
certificate "/etc/ssl/<%= $prefix.$host %>.fullchain.pem"
key "/etc/ssl/private/<%= $prefix.$host %>.key"
}
location * {
root "/htdocs/gemtexter/<%= $host %>"
directory auto index
}
}
<% } %>
# DTail special host
server "<%= $prefix %>dtail.dev" {
listen on * tls port 443
tls {
certificate "/etc/ssl/<%= $prefix %>dtail.dev.fullchain.pem"
key "/etc/ssl/private/<%= $prefix %>dtail.dev.key"
}
location * {
block return 302 "https://github.dtail.dev$REQUEST_URI"
}
}
# Irregular Ninja special host
server "<%= $prefix %>irregular.ninja" {
listen on * tls port 443
tls {
certificate "/etc/ssl/<%= $prefix %>irregular.ninja.fullchain.pem"
key "/etc/ssl/private/<%= $prefix %>irregular.ninja.key"
}
location * {
root "/htdocs/irregular.ninja"
directory auto index
}
}
# buetow.org special host.
server "<%= $prefix %>buetow.org" {
listen on * tls port 443
tls {
certificate "/etc/ssl/<%= $prefix %>buetow.org.fullchain.pem"
key "/etc/ssl/private/<%= $prefix %>buetow.org.key"
}
block return 302 "https://paul.buetow.org"
}
server "<%= $prefix %>paul.buetow.org" {
listen on * tls port 443
tls {
certificate "/etc/ssl/<%= $prefix %>paul.buetow.org.fullchain.pem"
key "/etc/ssl/private/<%= $prefix %>paul.buetow.org.key"
}
block return 302 "https://foo.zone/contact-information.html"
}
server "<%= $prefix %>tmp.buetow.org" {
listen on * tls port 443
tls {
certificate "/etc/ssl/<%= $prefix %>tmp.buetow.org.fullchain.pem"
key "/etc/ssl/private/<%= $prefix %>tmp.buetow.org.key"
}
root "/htdocs/buetow.org/tmp"
directory auto index
}
<%
our $primary = $is_primary->($vio0_ip);
our $prefix = $primary ? '' : 'www.';
%>
log connection
tcp protocol "gemini" {
tls keypair <%= $prefix %>foo.zone
tls keypair <%= $prefix %>buetow.org
}
relay "gemini4" {
listen on <%= $vio0_ip %> port 1965 tls
protocol "gemini"
forward to 127.0.0.1 port 11965
}
relay "gemini6" {
listen on <%= $ipv6address->($hostname) %> port 1965 tls
protocol "gemini"
forward to 127.0.0.1 port 11965
}
<% our $primary = $is_primary->($vio0_ip); our $prefix = $primary ? '' : 'www.'; %> pki "buetow_org_tls" cert "/etc/ssl/<%= $prefix %>buetow.org.fullchain.pem" pki "buetow_org_tls" key "/etc/ssl/private/<%= $prefix %>buetow.org.key" table aliases file:/etc/mail/aliases table virtualdomains file:/etc/mail/virtualdomains table virtualusers file:/etc/mail/virtualusers listen on socket listen on all tls pki "buetow_org_tls" hostname "<%= $prefix %>buetow.org" #listen on all action localmail mbox alias <aliases> action receive mbox virtual <virtualusers> action outbound relay match from any for domain <virtualdomains> action receive match from local for local action localmail match from local for any action outbound
rex commons
_
/_/_ .'''.
=O(_)))) ...' `.
jgs \_\ `. .'''
`..'

❯ perl ~/git/guprecords/src/guprecords --indir=./stats/ --count=20 --all Pos | System | Kernel | Uptime | Boot time 1 | sun | FreeBSD 10.1-RELEA.. | 502d 03:29:19 | Sun Aug 16 15:56:40 2015 2 | vulcan | Linux 3.10.0-1160... | 313d 13:19:39 | Sun Jul 25 18:32:25 2021 3 | uugrn | FreeBSD 10.2-RELEASE | 303d 15:19:35 | Tue Dec 22 21:33:07 2015 4 | uugrn | FreeBSD 11.0-RELEA.. | 281d 14:38:04 | Fri Oct 21 15:22:02 2016 5 | deltavega | Linux 3.10.0-957.2.. | 279d 11:15:00 | Sun Jun 30 11:42:38 2019 6 | vulcan | Linux 3.10.0-957.2.. | 279d 11:12:14 | Sun Jun 30 11:43:41 2019 7 | deltavega | Linux 3.10.0-1160... | 253d 04:42:22 | Sat Apr 24 13:34:34 2021 8 | host0 | FreeBSD 6.2-RELEAS.. | 240d 02:23:23 | Wed Jan 31 20:34:46 2007 9 | uugrn | FreeBSD 11.1-RELEA.. | 202d 21:12:41 | Sun May 6 18:06:17 2018 10 | tauceti | Linux 3.2.0-4-amd64 | 197d 18:45:40 | Mon Dec 16 19:47:54 2013 11 | pluto | Linux 2.6.32-5-amd64 | 185d 11:53:04 | Wed Aug 1 07:34:10 2012 12 | sun | FreeBSD 10.3-RELEA.. | 164d 22:31:55 | Sat Jul 22 18:47:21 2017 13 | vulcan | Linux 3.10.0-1160... | 161d 07:08:43 | Sun Feb 14 10:05:38 2021 14 | sun | FreeBSD 10.3-RELEA.. | 158d 21:18:36 | Sat Jan 27 10:18:57 2018 15 | uugrn | FreeBSD 11.1-RELEA.. | 157d 20:57:24 | Fri Nov 3 05:02:54 2017 16 | tauceti-f | Linux 3.2.0-3-amd64 | 150d 04:12:38 | Mon Sep 16 09:02:58 2013 17 | tauceti | Linux 3.2.0-4-amd64 | 149d 09:21:43 | Mon Aug 11 09:47:50 2014 18 | pluto | Linux 3.2.0-4-amd64 | 142d 02:57:31 | Mon Sep 8 01:59:02 2014 19 | tauceti-f | Linux 3.2.0-3-amd64 | 132d 22:46:26 | Mon May 6 11:11:35 2013 20 | keppler-16b | Darwin 13.4.0 | 131d 08:17:12 | Thu Jun 11 10:44:25 2015
❯ perl ~/git/guprecords/src/guprecords --indir=./stats/ --count=20 --total Pos | System | Kernel | Uptime | 1 | uranus | Linux 5.4.17-200.f.. | 1419d 19:05:39 | 2 | sun | FreeBSD 10.1-RELEA.. | 1363d 11:41:14 | 3 | vulcan | Linux 3.10.0-1160... | 1262d 20:27:48 | 4 | uugrn | FreeBSD 10.2-RELEASE | 1219d 15:10:16 | 5 | deltavega | Linux 3.10.0-957.2.. | 1115d 06:33:55 | 6 | pluto | Linux 2.6.32-5-amd64 | 1086d 10:44:05 | 7 | tauceti | Linux 3.2.0-4-amd64 | 846d 12:58:21 | 8 | tauceti-f | Linux 3.2.0-3-amd64 | 625d 07:16:39 | 9 | host0 | FreeBSD 6.2-RELEAS.. | 534d 19:50:13 | 10 | keppler-16b | Darwin 13.4.0 | 448d 06:15:00 | 11 | tauceti-e | Linux 3.2.0-4-amd64 | 415d 18:14:13 | 12 | moon | Darwin 18.7.0 | 326d 11:21:42 | 13 | callisto | Linux 4.0.4-303.fc.. | 303d 12:18:24 | 14 | alphacentauri | FreeBSD 10.1-RELEA.. | 300d 20:15:00 | 15 | earth | Linux 5.13.14-200... | 289d 08:05:05 | 16 | makemake | Linux 5.11.9-200.f.. | 286d 21:53:03 | 17 | london | Linux 3.2.0-4-amd64 | 258d 15:10:38 | 18 | fishbone | OpenBSD 4.1 .. | 223d 05:55:26 | 19 | sagittarius | Darwin 15.6.0 | 198d 23:53:59 | 20 | mars | Linux 3.2.0-4-amd64 | 190d 05:44:21 |
# Run command 'hostname' on server foo.example.com
./rubyfy.rb -c 'hostname' <<< foo.example.com
# Run command 'id' as root (via sudo) on all servers listed in the list file
# Do it on 10 servers in parallel
./rubyfy.rb --parallel 10 --root --command 'id' < serverlist.txt
# Run a fancy script in background on 50 servers in parallel
./rubyfy.rb -p 50 -r -b -c '/usr/local/scripts/fancy.zsh' < serverlist.txt
# Grep for specific process on both servers and write output to ./out/grep.txt
echo {foo,bar}.example.com | ./rubyfy.rb -p 10 -c 'pgrep -lf httpd' -n grep.txt
# Reboot server only if file /var/run/maintenance.lock does NOT exist!
echo foo.example.com |
./rubyfy.rb --root --command reboot --precondition /var/run/maintenance.lock
ssh dyndns@dyndnsserver /path/to/dyndns-update \
your.host.name. TYPE new-entry TIMEOUT
ssh dyndns@dyndnsserver /path/to/dyndns-update \ local.buetow.org. A 137.226.50.91 30
❯ ./cpuinfo cpuinfo (c) 1.0.2 Paul Buetow 11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz GenuineIntel 12288 KB cache p = 001 Physical processors c = 004 Cores s = 008 Siblings (Hyper-Threading enabled if s != c) v = 008 [v = p*c*(s != c ? 2 : 1)] Total logical CPUs Hyper-Threading is enabled 0003000 MHz each core 0012000 MHz total 0005990 Bogomips each processor (including virtual) 0023961 Bogomips total

Mon 20211213 50: work:5.92h
Tue 20211214 50: work:7.47h lunch:0.50h pet:0.42h
Wed 20211215 50: work:8.86h pet:0.50h
Thu 20211216 50: work:8.02h pet:0.50h
Fri 20211217 50: work:9.81h
* Sat 20211218 50: work:0.00h selfdevelopment:1.00h
* Sun 20211219 50: work:2.08h pet:1.00h selfdevelopment:-2.08h
================================================
balance:0.06h work:42.15h lunch:0.50h pet:2.42h selfdevelopment:-1.08h buffer:8.38h
▄ █ ▄ ▄ █ ▄ ▄ █ ▄
▄▀█▀▄ ▄▀█▀▄ ▄▀█▀▄
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ▀ ▀ ▀
█ ▄▄ ▄▄ █
█ █ █▀▀▀█ █ █ █ ▄▀ ▄▀▀▀▀▄ █▄ █ █▀▀▀▀▀▄ ▄▀▀▀▀▄ █ ▀▀▀█▀▀▀ ▄▀▀▀▀▄
█ ▀▀▀▀▀▀▀▀▀ █ █ ▄█ █ █ █ ▀▄ █ █▄▄▄▄▄▀ █▄▄▄▄▄▄█ █ █ █ █
█ ▄▀▀▀▀▀▀▀▀▀▀▀▄ █ █▀ ▀▄ ▀▄ ▄▀ █ ▀▄█ █ ▀▄ ▄ █ █ ▀▄ ▄▀
▀▄█▄█▄▄▄▄▄▄▄█▄█▄▀ ▀ ▀ ▀▀▀▀ ▀ ▀ ▀ ▀▀▀▀ ▀ ▀ ▀▀▀


. + . . . . . .
. . . *
. * . . . . . . + .
"You Are Here" . . + . . .
. | . . . . . .
| . . . +. + .
\|/ . . . .
. . V . * . . . . + .
+ . . . +
. . + .+. .
. . . + . . . . .
. . . . . . . . ! /
* . . . + . . - O -
. . . + . . * . . / |
. + . . . .. + .
. . . . * . * . +.. . *
. . . . . . . . + . . +
- the universe
❯ where learn
learn () {
man $(ls /bin /sbin /usr/bin /usr/sbin 2>/dev/null | shuf -n 1) |
sed -n "/^NAME/ { n;p;q }"
}
❯ learn
perltidy - a perl script indenter and reformatter
❯ learn
timedatectl - Control the system time and date
,_---~~~~~----._
_,,_,*^____ _____``*g*\"*,
____ _____ _ _ / __/ /' ^. / \ ^@q f
| _ \_ _|_ _(_) | @f | @)) | | @)) l 0 _/
| | | || |/ _` | | | \`/ \~____ / __ \_____/ \
| |_| || | (_| | | | | _l__l_ I
|____/ |_|\__,_|_|_| } [______] I
] | | | |
] ~ ~ |
| |
| |
// Available log levels. const ( None level = iota Fatal level = iota Error level = iota Warn level = iota Info level = iota Default level = iota Verbose level = iota Debug level = iota Devel level = iota Trace level = iota All level = iota )
{
"Client": {
"TermColorsEnable": true,
"TermColors": {
"Remote": {
"DelimiterAttr": "Dim",
"DelimiterBg": "Blue",
"DelimiterFg": "Cyan",
"RemoteAttr": "Dim",
"RemoteBg": "Blue",
"RemoteFg": "White",
"CountAttr": "Dim",
"CountBg": "Blue",
"CountFg": "White",
"HostnameAttr": "Bold",
"HostnameBg": "Blue",
"HostnameFg": "White",
"IDAttr": "Dim",
"IDBg": "Blue",
"IDFg": "White",
"StatsOkAttr": "None",
"StatsOkBg": "Green",
"StatsOkFg": "Black",
"StatsWarnAttr": "None",
"StatsWarnBg": "Red",
"StatsWarnFg": "White",
"TextAttr": "None",
"TextBg": "Black",
"TextFg": "White"
},
"Client": {
"DelimiterAttr": "Dim",
"DelimiterBg": "Yellow",
"DelimiterFg": "Black",
"ClientAttr": "Dim",
"ClientBg": "Yellow",
"ClientFg": "Black",
"HostnameAttr": "Dim",
"HostnameBg": "Yellow",
"HostnameFg": "Black",
"TextAttr": "None",
"TextBg": "Black",
"TextFg": "White"
},
"Server": {
"DelimiterAttr": "AttrDim",
"DelimiterBg": "BgCyan",
"DelimiterFg": "FgBlack",
"ServerAttr": "AttrDim",
"ServerBg": "BgCyan",
"ServerFg": "FgBlack",
"HostnameAttr": "AttrBold",
"HostnameBg": "BgCyan",
"HostnameFg": "FgBlack",
"TextAttr": "AttrNone",
"TextBg": "BgBlack",
"TextFg": "FgWhite"
},
"Common": {
"SeverityErrorAttr": "AttrBold",
"SeverityErrorBg": "BgRed",
"SeverityErrorFg": "FgWhite",
"SeverityFatalAttr": "AttrBold",
"SeverityFatalBg": "BgMagenta",
"SeverityFatalFg": "FgWhite",
"SeverityWarnAttr": "AttrBold",
"SeverityWarnBg": "BgBlack",
"SeverityWarnFg": "FgWhite"
},
"MaprTable": {
"DataAttr": "AttrNone",
"DataBg": "BgBlue",
"DataFg": "FgWhite",
"DelimiterAttr": "AttrDim",
"DelimiterBg": "BgBlue",
"DelimiterFg": "FgWhite",
"HeaderAttr": "AttrBold",
"HeaderBg": "BgBlue",
"HeaderFg": "FgWhite",
"HeaderDelimiterAttr": "AttrDim",
"HeaderDelimiterBg": "BgBlue",
"HeaderDelimiterFg": "FgWhite",
"HeaderSortKeyAttr": "AttrUnderline",
"HeaderGroupKeyAttr": "AttrReverse",
"RawQueryAttr": "AttrDim",
"RawQueryBg": "BgBlack",
"RawQueryFg": "FgCyan"
}
}
},
...
}
jsonschema -i dtail.json schemas/dtail.schema.json
% dtail --files /var/log/foo.log
% dmap --files /var/log/foo.log --query 'from TABLE select .... outfile result.csv'
% dtail /var/log/foo.log
% dcat --plain /etc/passwd > /etc/test % diff /etc/test /etc/passwd # Same content, no diff
% dgrep --plain --regex 'somethingspecial' /var/log/foo.log |
dmap --query 'from TABLE select .... outfile result.csv'
% awk '.....' < /some/file | dtail ....
% cat check_dtail.sh #!/bin/sh exec /usr/local/bin/dtailhealth --server localhost:2222
% export DTAIL_INTEGRATION_TEST_RUN_MODE=yes
% make . . . % go clean -testcache % go test -race -v ./integrationtests