The shebang line only supports a single argument. Spaces are included literally and there is no quoting. So the command you're running there is equivalent to this from a shell:
tr "'a' 'e'"
If you run that you'll see that tr
complains about the lack of a second argument. So why does your script not complain? Well that's the second problem. shebang cat
or grep
works because cat
and grep
takes name of an input file as an argument, and the shebang adds the script's name to the argument list. (That's required for the basic case of a #!/bin/sh
script to be executed as /bin/sh scriptname
)
You are therefore running
tr "'a' 'e'" yourscriptname
which gives tr
the 2 arguments it needs, and it then reads from stdin, translating from a set of characters you didn't intend to another set of characters you didn't intend.
If the shebang line had a fully functional shell parser, you could use
#!/usr/bin/tr 'a' 'e' <
And the filename added to the end would become the input. But shebang is just a simple thing in the kernel, not so featureful.
grep
takes a file argument, buttr
does not. – Tavel