diff options
| author | srdusr <[email protected]> | 2026-01-14 22:23:00 +0200 |
|---|---|---|
| committer | srdusr <[email protected]> | 2026-01-14 22:23:00 +0200 |
| commit | 4933f669f8338ca5e4c64cf0294818c5d15ed122 (patch) | |
| tree | 979ce6ffed0a4a59f65f47252ce9824a77be760e /data/packs/sysadmin.json | |
| parent | 695bf0df2ec48e67d716dad25711cdc2e96bf7f4 (diff) | |
| download | typerpunk-4933f669f8338ca5e4c64cf0294818c5d15ed122.tar.gz typerpunk-4933f669f8338ca5e4c64cf0294818c5d15ed122.zip | |
Make every passage long enough to be worth timing, and credit all of them
The dataset's median passage was 69 characters, about twelve words, which is
over in twelve seconds at an ordinary speed. Some packs were worse: shell had
a median of 46 and a shortest entry of 17. That is the reason packs felt
small. It was not the number of entries, which was 15 to 37 per pack, but the
length of each one.
Multiplayer had already hit this and worked around it: load_race_texts
filters to 120 characters or more. That filter left only 61 of 350 passages
eligible, 38 of them from two packs, so races repeated constantly and four
packs could never come up at all.
Both halves are fixed.
Content: 104 longer passages added across every pack. The command packs get
whole pipelines rather than single flags, which is how the tools are actually
used and what the explanations were always for. Prose packs get passages that
run 150 to 320 characters.
Selection: a floor of 120 characters. Prose packs draw from their long
entries where a pack holds at least five, so no pack is reduced to the same
few passages. The command packs chain consecutive entries into one drill,
which is the natural shape for them, and the explanations are collected so
each line is still described.
Measured over 400 draws per pack, every category now runs a median of 146 to
218 characters with a shortest draw of 120. The race pool went from 61 of 350
to 130 of 454.
Attribution: 24 passages had none and displayed nothing at all under the
text. They now say Unknown, which is the honest answer for a fact written for
the pack, and the pangram is credited as one. The results and typing screens
both fall back to Unknown rather than rendering an empty line, and the pack
name is shown beside the source.
Multiplayer results, three fixes:
- PB never appeared. A race has no mode of its own, so modeKey was undefined,
so recordResult never ran. Races share one key, because the passage is
whatever the server dealt and a per-passage best would never be beaten.
- Play Again started a solo test. A race carries standings and a solo run does
not, so the results screen can tell them apart and now queues for another
race. The end screen's own cleanup leaves the old room first.
- CONSISTENCY was the longest label on the screen and made the accuracy
column wider than the WPM column opposite it. It reads CON.
RaceText carries the pack name so the results can show it for a race the same
way single player does.
24 Rust tests and 3 browser tests pass.
Diffstat (limited to 'data/packs/sysadmin.json')
| -rw-r--r-- | data/packs/sysadmin.json | 262 |
1 files changed, 238 insertions, 24 deletions
diff --git a/data/packs/sysadmin.json b/data/packs/sysadmin.json index 4e1ec1f..15f29a5 100644 --- a/data/packs/sysadmin.json +++ b/data/packs/sysadmin.json @@ -1,26 +1,240 @@ [ - {"category":"sysadmin","language":"shell","attribution":"systemd","explanation":"Why a unit failed, without paging through the whole journal. -u scopes to the unit, -n limits the lines, --no-pager keeps it in the pipeline.","content":"journalctl -u nginx -n 50 --no-pager -p err"}, - {"category":"sysadmin","language":"shell","attribution":"systemd","explanation":"Lists units that failed at boot. The first thing to run on a machine that came up wrong.","content":"systemctl --failed --no-pager"}, - {"category":"sysadmin","language":"shell","attribution":"systemd","explanation":"Shows what a unit will actually run, including drop-ins, after every override has been merged.","content":"systemctl cat sshd.service && systemctl show sshd -p ExecStart"}, - {"category":"sysadmin","language":"shell","attribution":"systemd","explanation":"Ranks services by how long they delayed boot. The usual answer to a slow start is one unit near the top.","content":"systemd-analyze blame | head -15"}, - {"category":"sysadmin","language":"shell","attribution":"Disk","explanation":"Largest directories at this level, human readable. -x stays on one filesystem so it does not wander into /proc or a mount.","content":"du -xh --max-depth=1 / 2>/dev/null | sort -rh | head -15"}, - {"category":"sysadmin","language":"shell","attribution":"Disk","explanation":"A disk that reports free space but still refuses writes is usually out of inodes, not bytes.","content":"df -i | awk '$5+0 > 80 {print}'"}, - {"category":"sysadmin","language":"shell","attribution":"Disk","explanation":"Finds space held by deleted files that a process still has open. Deleting the file does not free the space until the handle closes.","content":"lsof +L1 2>/dev/null | awk '$7 > 100000000 {print $1, $7, $NF}'"}, - {"category":"sysadmin","language":"shell","attribution":"Processes","explanation":"The heaviest processes by resident memory. --sort takes a minus for descending order.","content":"ps -eo pid,user,rss,pcpu,comm --sort=-rss | head -12"}, - {"category":"sysadmin","language":"shell","attribution":"Processes","explanation":"What a process is actually waiting on. Reading its file descriptors and stack says more than another look at top.","content":"ls -l /proc/$PID/fd | head && cat /proc/$PID/wchan"}, - {"category":"sysadmin","language":"shell","attribution":"Processes","explanation":"Traces the system calls a command makes, with a count and timing summary rather than a wall of output.","content":"strace -c -f -p $PID 2>&1 | tail -20"}, - {"category":"sysadmin","language":"shell","attribution":"Network","explanation":"Listening sockets with the process behind each one. The modern replacement for netstat -tulpn.","content":"ss -ltnp | awk 'NR>1 {print $4, $6}'"}, - {"category":"sysadmin","language":"shell","attribution":"Network","explanation":"Which route the kernel will actually use for a destination, including the source address it will pick.","content":"ip route get 8.8.8.8"}, - {"category":"sysadmin","language":"shell","attribution":"Network","explanation":"Captures the start of connections only. -n skips DNS lookups, which otherwise generate the traffic you are trying to read.","content":"tcpdump -ni any 'tcp[tcpflags] & tcp-syn != 0' -c 20"}, - {"category":"sysadmin","language":"shell","attribution":"Network","explanation":"Resolves a name through a specific server, which is how you tell a stale local cache from a stale zone.","content":"dig +short @1.1.1.1 example.com A"}, - {"category":"sysadmin","language":"shell","attribution":"Permissions","explanation":"World-writable files outside the places that are meant to be. A common way a service ends up modifiable by anyone.","content":"find /etc /usr -type f -perm -o+w -ls 2>/dev/null"}, - {"category":"sysadmin","language":"shell","attribution":"Permissions","explanation":"Copies the ownership and mode of one file onto another, rather than typing the numbers and getting them wrong.","content":"chmod --reference=/etc/passwd /etc/passwd.new && chown --reference=/etc/passwd /etc/passwd.new"}, - {"category":"sysadmin","language":"shell","attribution":"Users","explanation":"Accounts with a real login shell, which is the set that can actually sign in.","content":"awk -F: '$7 !~ /(nologin|false)$/ {print $1, $7}' /etc/passwd"}, - {"category":"sysadmin","language":"shell","attribution":"Users","explanation":"Accounts with an empty password field. Should return nothing on any machine you care about.","content":"sudo awk -F: '$2 == \"\" {print $1}' /etc/shadow"}, - {"category":"sysadmin","language":"shell","attribution":"SSH","explanation":"Reuses one connection for subsequent sessions, so every later ssh or scp to the same host skips the handshake.","content":"ssh -o ControlMaster=auto -o ControlPersist=10m -o ControlPath=~/.ssh/cm-%r@%h:%p host"}, - {"category":"sysadmin","language":"shell","attribution":"SSH","explanation":"Forwards a remote port to the local machine, so a service bound to localhost on the server is reachable here.","content":"ssh -N -L 5432:127.0.0.1:5432 dbhost"}, - {"category":"sysadmin","language":"shell","attribution":"Backup","explanation":"Mirrors a tree, deletes what no longer exists on the source, and shows what it would do first. Never run this without -n the first time.","content":"rsync -avhn --delete /src/ /dest/"}, - {"category":"sysadmin","language":"shell","attribution":"Backup","explanation":"Streams a directory to another host without a temporary archive on either side.","content":"tar czf - /var/www | ssh backup 'cat > www-$(date +%F).tar.gz'"}, - {"category":"sysadmin","language":"shell","attribution":"Scheduling","explanation":"A cron entry that logs both streams. Without the redirect, cron mails the output to a mailbox nobody reads.","content":"0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1"}, - {"category":"sysadmin","language":"shell","attribution":"Containers","explanation":"Removes stopped containers, unused networks and dangling images. The usual cause of a full disk on a build host.","content":"docker system prune -af --volumes --filter 'until=168h'"} + { + "category": "sysadmin", + "language": "shell", + "attribution": "systemd", + "explanation": "Why a unit failed, without paging through the whole journal. -u scopes to the unit, -n limits the lines, --no-pager keeps it in the pipeline.", + "content": "journalctl -u nginx -n 50 --no-pager -p err" + }, + { + "category": "sysadmin", + "language": "shell", + "attribution": "systemd", + "explanation": "Lists units that failed at boot. The first thing to run on a machine that came up wrong.", + "content": "systemctl --failed --no-pager" + }, + { + "category": "sysadmin", + "language": "shell", + "attribution": "systemd", + "explanation": "Shows what a unit will actually run, including drop-ins, after every override has been merged.", + "content": "systemctl cat sshd.service && systemctl show sshd -p ExecStart" + }, + { + "category": "sysadmin", + "language": "shell", + "attribution": "systemd", + "explanation": "Ranks services by how long they delayed boot. The usual answer to a slow start is one unit near the top.", + "content": "systemd-analyze blame | head -15" + }, + { + "category": "sysadmin", + "language": "shell", + "attribution": "Disk", + "explanation": "Largest directories at this level, human readable. -x stays on one filesystem so it does not wander into /proc or a mount.", + "content": "du -xh --max-depth=1 / 2>/dev/null | sort -rh | head -15" + }, + { + "category": "sysadmin", + "language": "shell", + "attribution": "Disk", + "explanation": "A disk that reports free space but still refuses writes is usually out of inodes, not bytes.", + "content": "df -i | awk '$5+0 > 80 {print}'" + }, + { + "category": "sysadmin", + "language": "shell", + "attribution": "Disk", + "explanation": "Finds space held by deleted files that a process still has open. Deleting the file does not free the space until the handle closes.", + "content": "lsof +L1 2>/dev/null | awk '$7 > 100000000 {print $1, $7, $NF}'" + }, + { + "category": "sysadmin", + "language": "shell", + "attribution": "Processes", + "explanation": "The heaviest processes by resident memory. --sort takes a minus for descending order.", + "content": "ps -eo pid,user,rss,pcpu,comm --sort=-rss | head -12" + }, + { + "category": "sysadmin", + "language": "shell", + "attribution": "Processes", + "explanation": "What a process is actually waiting on. Reading its file descriptors and stack says more than another look at top.", + "content": "ls -l /proc/$PID/fd | head && cat /proc/$PID/wchan" + }, + { + "category": "sysadmin", + "language": "shell", + "attribution": "Processes", + "explanation": "Traces the system calls a command makes, with a count and timing summary rather than a wall of output.", + "content": "strace -c -f -p $PID 2>&1 | tail -20" + }, + { + "category": "sysadmin", + "language": "shell", + "attribution": "Network", + "explanation": "Listening sockets with the process behind each one. The modern replacement for netstat -tulpn.", + "content": "ss -ltnp | awk 'NR>1 {print $4, $6}'" + }, + { + "category": "sysadmin", + "language": "shell", + "attribution": "Network", + "explanation": "Which route the kernel will actually use for a destination, including the source address it will pick.", + "content": "ip route get 8.8.8.8" + }, + { + "category": "sysadmin", + "language": "shell", + "attribution": "Network", + "explanation": "Captures the start of connections only. -n skips DNS lookups, which otherwise generate the traffic you are trying to read.", + "content": "tcpdump -ni any 'tcp[tcpflags] & tcp-syn != 0' -c 20" + }, + { + "category": "sysadmin", + "language": "shell", + "attribution": "Network", + "explanation": "Resolves a name through a specific server, which is how you tell a stale local cache from a stale zone.", + "content": "dig +short @1.1.1.1 example.com A" + }, + { + "category": "sysadmin", + "language": "shell", + "attribution": "Permissions", + "explanation": "World-writable files outside the places that are meant to be. A common way a service ends up modifiable by anyone.", + "content": "find /etc /usr -type f -perm -o+w -ls 2>/dev/null" + }, + { + "category": "sysadmin", + "language": "shell", + "attribution": "Permissions", + "explanation": "Copies the ownership and mode of one file onto another, rather than typing the numbers and getting them wrong.", + "content": "chmod --reference=/etc/passwd /etc/passwd.new && chown --reference=/etc/passwd /etc/passwd.new" + }, + { + "category": "sysadmin", + "language": "shell", + "attribution": "Users", + "explanation": "Accounts with a real login shell, which is the set that can actually sign in.", + "content": "awk -F: '$7 !~ /(nologin|false)$/ {print $1, $7}' /etc/passwd" + }, + { + "category": "sysadmin", + "language": "shell", + "attribution": "Users", + "explanation": "Accounts with an empty password field. Should return nothing on any machine you care about.", + "content": "sudo awk -F: '$2 == \"\" {print $1}' /etc/shadow" + }, + { + "category": "sysadmin", + "language": "shell", + "attribution": "SSH", + "explanation": "Reuses one connection for subsequent sessions, so every later ssh or scp to the same host skips the handshake.", + "content": "ssh -o ControlMaster=auto -o ControlPersist=10m -o ControlPath=~/.ssh/cm-%r@%h:%p host" + }, + { + "category": "sysadmin", + "language": "shell", + "attribution": "SSH", + "explanation": "Forwards a remote port to the local machine, so a service bound to localhost on the server is reachable here.", + "content": "ssh -N -L 5432:127.0.0.1:5432 dbhost" + }, + { + "category": "sysadmin", + "language": "shell", + "attribution": "Backup", + "explanation": "Mirrors a tree, deletes what no longer exists on the source, and shows what it would do first. Never run this without -n the first time.", + "content": "rsync -avhn --delete /src/ /dest/" + }, + { + "category": "sysadmin", + "language": "shell", + "attribution": "Backup", + "explanation": "Streams a directory to another host without a temporary archive on either side.", + "content": "tar czf - /var/www | ssh backup 'cat > www-$(date +%F).tar.gz'" + }, + { + "category": "sysadmin", + "language": "shell", + "attribution": "Scheduling", + "explanation": "A cron entry that logs both streams. Without the redirect, cron mails the output to a mailbox nobody reads.", + "content": "0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1" + }, + { + "category": "sysadmin", + "language": "shell", + "attribution": "Containers", + "explanation": "Removes stopped containers, unused networks and dangling images. The usual cause of a full disk on a build host.", + "content": "docker system prune -af --volumes --filter 'until=168h'" + }, + { + "category": "sysadmin", + "content": "rsync -avz --delete --exclude='.git' ./site/ deploy@host:/var/www/site/", + "attribution": "rsync", + "explanation": "The trailing slash on the source copies the contents rather than the directory itself. --delete removes files on the far side that no longer exist locally, which makes the copy a mirror.", + "language": "shell" + }, + { + "category": "sysadmin", + "content": "ss -tulpn | awk 'NR > 1 {print $1, $5, $7}' | sort -u", + "attribution": "ss", + "explanation": "ss has replaced netstat on Linux. -tulpn lists listening TCP and UDP sockets with the owning process, and the awk trims it to protocol, address and program.", + "language": "shell" + }, + { + "category": "sysadmin", + "content": "systemctl list-units --type=service --state=failed --no-legend | awk '{print $1}'", + "attribution": "systemctl", + "explanation": "--no-legend drops the header and footer that are meant for a human reader, which leaves output a script can consume directly.", + "language": "shell" + }, + { + "category": "sysadmin", + "content": "find /var/log -type f -size +100M -exec ls -lh {} + | awk '{print $5, $9}'", + "attribution": "find", + "explanation": "-exec with a trailing plus batches many paths into one command, rather than the semicolon form that starts a fresh process for every file.", + "language": "shell" + }, + { + "category": "sysadmin", + "content": "dig +short TXT _dmarc.example.com @1.1.1.1", + "attribution": "dig", + "explanation": "+short prints the record value alone. Naming a resolver after the at sign asks that server directly, which bypasses whatever the local system has cached.", + "language": "shell" + }, + { + "category": "sysadmin", + "content": "openssl x509 -in cert.pem -noout -subject -issuer -dates", + "attribution": "openssl", + "explanation": "Reads a certificate without connecting to anything. -dates prints notBefore and notAfter, which is the quickest way to answer when a certificate expires.", + "language": "shell" + }, + { + "category": "sysadmin", + "content": "df -h --output=source,pcent,target | awk 'NR > 1 && $2+0 > 80'", + "attribution": "df", + "explanation": "Adding zero to a field forces awk to treat it as a number, so the percent sign is discarded and the comparison works. This lists only filesystems over 80 percent full.", + "language": "shell" + }, + { + "category": "sysadmin", + "content": "ip -br -c addr show | awk '$2 == \"UP\" {print $1, $3}'", + "attribution": "ip", + "explanation": "-br is brief output, one line per interface, which is far easier to parse than the default. This prints the name and address of every interface currently up.", + "language": "shell" + }, + { + "category": "sysadmin", + "content": "lsof -nP -iTCP -sTCP:LISTEN | awk 'NR > 1 {print $1, $2, $9}'", + "attribution": "lsof", + "explanation": "-n and -P stop lsof resolving names and ports, which is much faster and gives numbers you can match against configuration.", + "language": "shell" + }, + { + "category": "sysadmin", + "content": "for u in $(cut -d: -f1 /etc/passwd); do echo \"$u $(crontab -lu \"$u\" 2>/dev/null | grep -c '^[^#]')\"; done", + "attribution": "shell", + "explanation": "Walks every account and counts its active cron entries. Redirecting standard error hides the complaint for users who have no crontab at all.", + "language": "shell" + } ] |