Problem
small-tools/install.sh installs tldr and seeds its cache, but after a fresh
run tldr <command> does not work — it errors with:
Page cache not found. Please run `tldr --update` to download the cache.
The client actually installed on the target is tealdeer 1.6.1 (dpkg -S $(which tldr) → tealdeer, /usr/bin/tldr), and the install step that is
supposed to populate the cache fails:
$ tldr --update
Could not update cache
Caused by:
0: Could not decompress downloaded ZIP archive
1: invalid Zip archive: Could not find central directory end
$ echo $?
1
Because this is a hard failure, the cache is never written and every page
lookup fails.
Why it also breaks the rest of the install
tldr --update is line 147 of small-tools/install.sh, and it sits inside
the long && \ chain:
# small-tools/install.sh:145-150
# tldr update
mkdir -p /home/"${USER_NAME}"/.local/share/tldr && \
tldr --update && \ # <- exits 1 here
# delete old tmux plugin manager, avoid problems
rm -rf /home/"${USER_NAME}"/.tmux/plugins/tpm && \
...
Since tldr --update returns 1, the && chain short-circuits and every
subsequent step is silently skipped — tpm clone, tmux config copy,
tmux-powerline setup, etc. A cosmetic "nice to have" (tldr cache) aborts the
whole tail of the installer.
Root causes
-
Non-fatal step treated as fatal. A failed tldr cache download should not
abort the installer. It is chained with &&, so it does.
-
Wrong cache directory (and an always-true guard). Lines 11-12 and 146
operate on ~/.local/share/tldr (the old Node/C tldr client layout).
tealdeer 1.6.1 ignores that path entirely; its real cache is
~/.cache/tealdeer/tldr-pages/. So the rm -rf / mkdir -p are dead no-ops
for the client that is actually installed. Worse, the guard on line 11 is
if [ -n "/home/${USER_NAME}/.local/share/tldr" ] — a test on a non-empty
string literal, which is always true, so the rm -rf always runs.
The same [ -n ... ] / [ -z ... ]-on-a-literal antipattern repeats at
lines 15, 19, 23; these should be [ -d ... ] / [ ! -d ... ] path tests.
$ ls -d ~/.local/share/tldr # script touches this
No such file or directory
$ ls -d ~/.cache/tealdeer/tldr-pages # tealdeer actually uses this
/home/yunchien/.cache/tealdeer/tldr-pages
-
Package mismatch. The apt list installs package tldr (apt-cache policy tldr → candidate 0.9.2-5), but the binary present is the separate
tealdeer package (1.6.1). The two clients have different cache layouts and
different update mechanics, which is why the ~/.local/share/tldr handling
no longer matches reality.
Evidence — working manual recovery
tealdeer's own downloader produced the broken ZIP, but fetching the release
asset directly yields a valid archive, and unzipping it into the tealdeer cache
makes tldr work immediately:
curl -sSL -o /tmp/tldr.zip \
https://github.com/tldr-pages/tldr/releases/latest/download/tldr.zip
# -> HTTP 200, 19 MB, "Zip archive data" (valid)
mkdir -p ~/.cache/tealdeer/tldr-pages
unzip -oq /tmp/tldr.zip -d ~/.cache/tealdeer/tldr-pages
tldr tar # -> renders correctly
Secondary: fish tab-completion for tldr does not load
The tealdeer completion ships at /usr/share/fish/completions/tldr.fish, but
that directory is not part of fish's $fish_complete_path (which scans the
vendor_completions.d dirs, plus the user/etc dirs — tealdeer ships nothing
there). So tldr --<TAB> (e.g. --language) completes nothing. Sourcing the
file by hand proves the file itself is fine:
$ fish -c 'complete -C "tldr --la"' # nothing
$ fish -c 'source /usr/share/fish/completions/tldr.fish; complete -C "tldr --la"'
--language Override the language
Fix that works: copy the completion into a directory fish does scan:
mkdir -p ~/.config/fish/completions
cp /usr/share/fish/completions/tldr.fish ~/.config/fish/completions/
Proposed change
In small-tools/install.sh:
-
Decouple the cache update from the && chain so a failed download cannot
abort the installer, e.g.:
tldr --update || echo "WARN: tldr cache update failed; run 'tldr --update' later" >&2
-
Add a robust fallback when tldr --update fails: download the release zip
via curl and unzip into the correct tealdeer cache dir
(~/.cache/tealdeer/tldr-pages/).
-
Drop / fix the ~/.local/share/tldr handling (lines 11-12, 146) — it
targets the wrong layout for tealdeer. Use ~/.cache/tealdeer/ if any
pre-clean is needed.
-
Pin the client. Decide on tealdeer explicitly (install the tealdeer
package, not tldr) so the cache path and update behaviour are predictable.
-
Install the fish completion to a path fish actually scans
(~/.config/fish/completions/tldr.fish), since the snap fish ignores
/usr/share/fish/completions.
Files in scope
small-tools/install.sh (lines 10-13, 87, 145-147)
small-tools/remove.sh (lines 44-45 mirror the wrong ~/.local/share/tldr
path)
Notes
- The broken-ZIP failure from tealdeer's own downloader was reproducible in this
environment; the curl + unzip path is a reliable workaround and a good
fallback to bake into the installer.
- Minor doc point: tealdeer's traditional-Chinese set (
pages.zh_TW, ~305
pages) is sparse and does not include common commands like tar. For Chinese
output tldr -L zh <cmd> (simplified) is the practical choice. Two gotchas
worth a one-line doc note: -L is capital L (lowercase -l is --list),
and the language code uses an underscore (zh_TW), not a hyphen
(zh-TW). Document wherever tldr usage appears (README.adoc:477-478,
small-tools/README.adoc:175-176, small-tools/README_zh.adoc:120-121).
Problem
small-tools/install.shinstallstldrand seeds its cache, but after a freshrun
tldr <command>does not work — it errors with:The client actually installed on the target is tealdeer 1.6.1 (
dpkg -S $(which tldr)→tealdeer,/usr/bin/tldr), and the install step that issupposed to populate the cache fails:
Because this is a hard failure, the cache is never written and every page
lookup fails.
Why it also breaks the rest of the install
tldr --updateis line 147 ofsmall-tools/install.sh, and it sits insidethe long
&& \chain:Since
tldr --updatereturns1, the&&chain short-circuits and everysubsequent step is silently skipped — tpm clone, tmux config copy,
tmux-powerline setup, etc. A cosmetic "nice to have" (tldr cache) aborts the
whole tail of the installer.
Root causes
Non-fatal step treated as fatal. A failed tldr cache download should not
abort the installer. It is chained with
&&, so it does.Wrong cache directory (and an always-true guard). Lines 11-12 and 146
operate on
~/.local/share/tldr(the old Node/Ctldrclient layout).tealdeer 1.6.1 ignores that path entirely; its real cache is
~/.cache/tealdeer/tldr-pages/. So therm -rf/mkdir -pare dead no-opsfor the client that is actually installed. Worse, the guard on line 11 is
if [ -n "/home/${USER_NAME}/.local/share/tldr" ]— a test on a non-emptystring literal, which is always true, so the
rm -rfalways runs.The same
[ -n ... ]/[ -z ... ]-on-a-literal antipattern repeats atlines 15, 19, 23; these should be
[ -d ... ]/[ ! -d ... ]path tests.Package mismatch. The apt list installs package
tldr(apt-cache policy tldr→ candidate0.9.2-5), but the binary present is the separatetealdeerpackage (1.6.1). The two clients have different cache layouts anddifferent update mechanics, which is why the
~/.local/share/tldrhandlingno longer matches reality.
Evidence — working manual recovery
tealdeer's own downloader produced the broken ZIP, but fetching the release
asset directly yields a valid archive, and unzipping it into the tealdeer cache
makes
tldrwork immediately:Secondary: fish tab-completion for tldr does not load
The tealdeer completion ships at
/usr/share/fish/completions/tldr.fish, butthat directory is not part of fish's
$fish_complete_path(which scans thevendor_completions.ddirs, plus the user/etc dirs — tealdeer ships nothingthere). So
tldr --<TAB>(e.g.--language) completes nothing. Sourcing thefile by hand proves the file itself is fine:
Fix that works: copy the completion into a directory fish does scan:
Proposed change
In
small-tools/install.sh:Decouple the cache update from the
&&chain so a failed download cannotabort the installer, e.g.:
Add a robust fallback when
tldr --updatefails: download the release zipvia curl and unzip into the correct tealdeer cache dir
(
~/.cache/tealdeer/tldr-pages/).Drop / fix the
~/.local/share/tldrhandling (lines 11-12, 146) — ittargets the wrong layout for tealdeer. Use
~/.cache/tealdeer/if anypre-clean is needed.
Pin the client. Decide on tealdeer explicitly (install the
tealdeerpackage, not
tldr) so the cache path and update behaviour are predictable.Install the fish completion to a path fish actually scans
(
~/.config/fish/completions/tldr.fish), since the snap fish ignores/usr/share/fish/completions.Files in scope
small-tools/install.sh(lines 10-13, 87, 145-147)small-tools/remove.sh(lines 44-45 mirror the wrong~/.local/share/tldrpath)
Notes
environment; the curl + unzip path is a reliable workaround and a good
fallback to bake into the installer.
pages.zh_TW, ~305pages) is sparse and does not include common commands like
tar. For Chineseoutput
tldr -L zh <cmd>(simplified) is the practical choice. Two gotchasworth a one-line doc note:
-Lis capital L (lowercase-lis--list),and the language code uses an underscore (
zh_TW), not a hyphen(
zh-TW). Document wherever tldr usage appears (README.adoc:477-478,small-tools/README.adoc:175-176,small-tools/README_zh.adoc:120-121).