* Installer: wrap install.sh in a function so a piped install cannot report curl (56)
`curl -fsSL https://unsloth.ai/install.sh | sh` makes sh the READER of a pipe.
The file is ~150KB, far more than a pipe buffer holds, so a top-level `exit` left
sh dead with thousands of lines unread. The write end then failed and curl
appended
curl: (56) Failure writing output to destination, passed 16357 returned 0
after the installer's own message, which reads as a download failure rather than
the real diagnosis. 29 of the 35 exits are in the first half of the file, so every
early failure on every platform looked like a bad download.
Measured, piping this file into sh and forcing an early exit:
before: writer rc=141 (SIGPIPE) reader rc=1
after: writer rc=0 reader rc=1
Through a real curl against a local server, curl rc went 23 -> 0 while the
installer's own exit code kept propagating.
Defining a function forces sh to parse to the closing brace before running
anything, so the pipe is always drained. install.ps1 has always had this shape
(Install-UnslothStudio invoked at the end of the file); this brings install.sh
into line.
Deliberately not reindented. Shell ignores leading whitespace, so the diff stays
two hunks instead of 4400 reflowed lines, and `exit` still exits the shell from
inside a function, so no control flow changes.
tests/sh/test_install_pipe_safety.sh pins both halves of the contract: the writer
must survive, and the installer's real exit code must still reach the caller. It
fails against the unwrapped file (writer rc=141).
* Tighten the pipe-safety comments
Compress the install.sh wrapper rationale and the test header down to the
parts that are not obvious from the code. Comments only, the parsed command
tree of both files is byte identical.
---------
Co-authored-by: danielhanchen <unslothai@gmail.com>