1

From Glenn's reply:

Read your execve(2) man page. The limitation on a single optional argument is OS dependent. Linux treats all words after the interpreter as one single argument

If you want to do this:

#! /path/to/interpreter arg1 arg2 arg3

You should in fact do this

#!/bin/sh
exec /path/to/interpreter arg1 arg2 arg3 "$@"

If I want to write a script which contains some code in the script language,:

#! /path/to/interpreter arg1 arg2 arg3

<script content in the script language>

according to Glenn's reply, I should instead write the script as:

#!/bin/sh
exec /path/to/interpreter arg1 arg2 arg3 "$@"

Then where should I write <script content in the script langauge>? Since it is written in the script language but not in the shell language, so it can't be placed in the the shell script, correct? Where should I place it?

Thanks.

2

You'll have to trick the interpretor into ignoring the exec line, and put the script contents normally in the file. Options include:

  • Polyglot scripts, where the exec command is written so that it looks like comment or a string or similar to the actual interpretor. Examples:
  • feed the script to the interpretor with the initial lines stripped off
3

In addition to the options that muru gave, there is another option. Depending on the complexity and length of the script, you can put the script inside the shell script (whether it's generally useful is another question!) Using the "here-document" mechanism, you can have the shell pipe embedded text into another program, like this:

test.sh

#!/bin/sh
exec /usr/bin/python3 <<EOF
import datetime
print("The time is now "+str(datetime.datetime.now()))
EOF

I wouldn't use this if the program is very large, because it's harder to edit these kinds of scripts; they're embedded in another language, so you have to extract the script to do any modifications if you want to test them.

As an oddity, note that the shell still expands shell variables and interprets special characters using this method:

#!/bin/sh
exec /usr/bin/python3 <<EOF
print("The current user is $USER and date is $(date).")
EOF

Returns The user is erik and date is Fri Apr 6 22:14:23 MDT 2018.

  • Only if the token after << is (wholly) unquoted. This is explained in the wikipedia page you linked, or e.g. gnu.org/software/bash/manual/html_node/… – dave_thompson_085 Apr 7 '18 at 4:26
  • Also, the script effectively loses stdin... – muru Apr 7 '18 at 4:31
  • There are plenty of gotchas with this method! As a quick-and-dirty solution it's OK, but there are definitely better ideas. – ErikF Apr 7 '18 at 4:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.