Of course "spawning a shell" can be very cheap, as you are already in a shell, it's just fork() plus some initialization code (compared to fork() plus exec() for running a non-shell program)
Note that shells must try to interpret at least any text file for which the system returns ENOEXEC [1]
1: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3... Read subsection 1.e.i.b