Fix non-compliant -i parsing to prevent argument-shifting bugs in sh/dash
### Title:
**Fix non-compliant `-i` parsing to prevent argument-shifting bugs in `sh`/`dash`**
---
### Description:
**Summary**
The current implementation of the `-i` option uses a "hack" to simulate optional arguments within `getopts`. By manually manipulating `OPTIND` and "peeking" at the next positional parameter, the script violates POSIX utility guidelines and causes desynchronization in minimalist shells like `dash`.
This behavior is a known point of failure for automation tools and wrappers, notably documented in **nixos-anywhere [issue #615](https://github.com/nix-community/nixos-anywhere/issues/615)**.
**The Problem**
`getopts` is not designed to handle optional arguments. In `dash` (the default `/bin/sh` on many systems), manual modification of `OPTIND` during the loop often leads to:
1. The target `USER_HOST` being incorrectly shifted away.
2. Heuristics misidentifying a hostname as an identity file if a local file with a similar name exists.
3. Errors like `Too many arguments` or `Missing hostname` when the script is called programmatically.
**Proposed Solution**
To make the script fully POSIX-compliant and robust across all shells, I suggest removing the `-i` parsing from the `getopts` state machine and replacing the argument processing with a manual `while`/`case` loop.
A manual loop allows for safe "lookahead" logic without interfering with the shell's internal `getopts` pointers. This ensures that:
- `USER_HOST` is always correctly identified as the first non-option argument.
- The script remains compatible with `dash`, `ksh`, and other strict `sh` implementations.
- Automation wrappers can reliably pass arguments without fear of the script "swallowing" parameters.
**Example of the more robust approach:**
```sh
while [ $# -gt 0 ]; do
case "$1" in
-i)
shift
if [ -r "$1" ] || [ -r "$1.pub" ]; then
use_id_file "$1"
shift
else
use_id_file "$DEFAULT_PUB_ID_FILE"
fi
;;
-p) SSH_PORT="$2"; shift 2 ;;
# ... handle other flags ...
*) break ;; # First non-option is USER_HOST
esac
done
```
By moving to a standard manual parsing loop, we preserve the "user-friendly" optional argument of `-i` while gaining the reliability required for modern deployment workflows.
issue