Pregunta

I have this script on my system:

#! /bin/grep cat

caterpillar
cat
lol
morecat

When I run it, I get the output as expected,

#! /bin/grep cat
caterpillar
cat
morecat

But, if I use tr instead, with the script

#! /usr/bin/tr 'a' 'e'

caterpillar
cat
lol
morecat

I expect to get

#! /usr/bin/tr 'a' 'e'

ceterpiller
cet
lol
morecet

But instead nothing is printed, and if I manually type cat, I get c/t. How can the script be changed to behave like the first?

¿Fue útil?

Solución

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top