É simplificar a interface. A alternativa para fork e exec seria algo como o Windows ' função CreateProcess . Observe quantos parâmetros CreateProcess tem e muitos deles são estruturas com ainda mais parâmetros. Isso porque tudo que você deseja controlar sobre o novo processo deve ser passado para CreateProcess . Na verdade, CreateProcess não tem parâmetros suficientes, então a Microsoft precisou adicionar CreateProcessAsUser e CreateProcessWithLogonW .
Com o modelo fork/exec , você não precisa de todos esses parâmetros. Em vez disso, determinados atributos do processo são preservados em exec . Isso permite que você use fork e, em seguida, altere os atributos de processo desejados (usando as mesmas funções que você usaria normalmente) e , em seguida, exec . No Linux, fork não possui parâmetros e execve tem apenas 3: o programa a ser executado, a linha de comando para fornecê-lo e seu ambiente. (Há outras funções exec , mas elas são apenas wrappers em torno de execve fornecidas pela biblioteca C para simplificar os casos de uso comuns.)
Se você quiser iniciar um processo com um diretório atual diferente: fork , chdir , exec .
Se você quiser redirecionar stdin / stdout: fork , feche / abra arquivos, exec .
Se você quiser trocar de usuário: fork , setuid , exec .
Todas essas coisas podem ser combinadas conforme necessário. Se alguém apresentar um novo tipo de atributo de processo, você não precisará alterar fork e exec .
Como larsks mencionou, a maioria dos Unixes modernos usa copy-on-write, portanto fork não envolve sobrecarga significativa.