If you use htty to wrap vim you get a process tree like this:
python
└── ht
└── sh
└── vim
It might be cleaner to instead do this:
htty uses a shell because ht used a shell, but if the user wants a shell involved, it would be better to let them specify it, because maybe they want something besides /bin/sh.
Whatever antics we rely on the shell for, we can likely achieve in the rust code which handles the subprocess.
This would be controlled by a flag so that we can still use sh for commands which require shell parsing like cat ./bar.txt | grep bar, but then we can avoid using sh for commands that don't need it, like vim ./bar.txt.
Excluding sh would reduce the risk of problematic behavior. For instance, this should just fail because $(/path/to/some/malware.sh) is not a valid filename, but if sh is involved it will run that script.
vim $(/path/to/some/malware.sh)