Multiple arguments in shebang

Clash Royale CLAN TAG#URR8PPP
up vote
17
down vote
favorite
I am wondering whether there is a general way of passing multiple options to an executable via the shebang line (#!).
I use NixOS, and the first part of the shebang in any script I write is usually /usr/bin/env. The problem I encounter then is that everything that comes after is interpreted as a single file or directory by the system.
Suppose, for example, that I want to write a script to be executed by bash in posix mode. The naive way of writing the shebang would be:
#!/usr/bin/env bash --posix
but trying to execute the resulting script produces the following error:
/usr/bin/env: âÂÂbash --posixâÂÂ: No such file or directory
I am aware of this post, but I was wondering whether there was a more general and cleaner solution.
EDIT: I know that for Guile scripts, there is a way to achieve what I want, documented in Section 4.3.4 of the manual:
#!/usr/bin/env sh
exec guile -l fact -e '(@ (fac) main)' -s "$0" "$@"
!#
The trick, here, is that the second line (starting with exec) is interpreted as code by sh but, being in the #! ... !# block, as a comment, and thus ignored, by the Guile interpreter.
Would it not be possible to generalize this method to any interpreter?
Second EDIT: After playing around a little bit, it seems that, for interpreters that can read their input from stdin, the following method would work:
#!/usr/bin/env sh
sed '1,2d' "$0" | bash --verbose --posix /dev/stdin; exit;
It's probably not optimal, though, as the sh process lives until the interpreter has finished its job. Any feedback or suggestion would be appreciated.
scripting environment-variables posix arguments shebang
add a comment |Â
up vote
17
down vote
favorite
I am wondering whether there is a general way of passing multiple options to an executable via the shebang line (#!).
I use NixOS, and the first part of the shebang in any script I write is usually /usr/bin/env. The problem I encounter then is that everything that comes after is interpreted as a single file or directory by the system.
Suppose, for example, that I want to write a script to be executed by bash in posix mode. The naive way of writing the shebang would be:
#!/usr/bin/env bash --posix
but trying to execute the resulting script produces the following error:
/usr/bin/env: âÂÂbash --posixâÂÂ: No such file or directory
I am aware of this post, but I was wondering whether there was a more general and cleaner solution.
EDIT: I know that for Guile scripts, there is a way to achieve what I want, documented in Section 4.3.4 of the manual:
#!/usr/bin/env sh
exec guile -l fact -e '(@ (fac) main)' -s "$0" "$@"
!#
The trick, here, is that the second line (starting with exec) is interpreted as code by sh but, being in the #! ... !# block, as a comment, and thus ignored, by the Guile interpreter.
Would it not be possible to generalize this method to any interpreter?
Second EDIT: After playing around a little bit, it seems that, for interpreters that can read their input from stdin, the following method would work:
#!/usr/bin/env sh
sed '1,2d' "$0" | bash --verbose --posix /dev/stdin; exit;
It's probably not optimal, though, as the sh process lives until the interpreter has finished its job. Any feedback or suggestion would be appreciated.
scripting environment-variables posix arguments shebang
1
Related: unix.stackexchange.com/questions/63979/â¦
â Kusalananda
Oct 22 '17 at 11:50
1
Also relevant: How to pass arguments to the shebang interpreter when executing a script?.
â Stephen Kitt
Oct 22 '17 at 11:54
add a comment |Â
up vote
17
down vote
favorite
up vote
17
down vote
favorite
I am wondering whether there is a general way of passing multiple options to an executable via the shebang line (#!).
I use NixOS, and the first part of the shebang in any script I write is usually /usr/bin/env. The problem I encounter then is that everything that comes after is interpreted as a single file or directory by the system.
Suppose, for example, that I want to write a script to be executed by bash in posix mode. The naive way of writing the shebang would be:
#!/usr/bin/env bash --posix
but trying to execute the resulting script produces the following error:
/usr/bin/env: âÂÂbash --posixâÂÂ: No such file or directory
I am aware of this post, but I was wondering whether there was a more general and cleaner solution.
EDIT: I know that for Guile scripts, there is a way to achieve what I want, documented in Section 4.3.4 of the manual:
#!/usr/bin/env sh
exec guile -l fact -e '(@ (fac) main)' -s "$0" "$@"
!#
The trick, here, is that the second line (starting with exec) is interpreted as code by sh but, being in the #! ... !# block, as a comment, and thus ignored, by the Guile interpreter.
Would it not be possible to generalize this method to any interpreter?
Second EDIT: After playing around a little bit, it seems that, for interpreters that can read their input from stdin, the following method would work:
#!/usr/bin/env sh
sed '1,2d' "$0" | bash --verbose --posix /dev/stdin; exit;
It's probably not optimal, though, as the sh process lives until the interpreter has finished its job. Any feedback or suggestion would be appreciated.
scripting environment-variables posix arguments shebang
I am wondering whether there is a general way of passing multiple options to an executable via the shebang line (#!).
I use NixOS, and the first part of the shebang in any script I write is usually /usr/bin/env. The problem I encounter then is that everything that comes after is interpreted as a single file or directory by the system.
Suppose, for example, that I want to write a script to be executed by bash in posix mode. The naive way of writing the shebang would be:
#!/usr/bin/env bash --posix
but trying to execute the resulting script produces the following error:
/usr/bin/env: âÂÂbash --posixâÂÂ: No such file or directory
I am aware of this post, but I was wondering whether there was a more general and cleaner solution.
EDIT: I know that for Guile scripts, there is a way to achieve what I want, documented in Section 4.3.4 of the manual:
#!/usr/bin/env sh
exec guile -l fact -e '(@ (fac) main)' -s "$0" "$@"
!#
The trick, here, is that the second line (starting with exec) is interpreted as code by sh but, being in the #! ... !# block, as a comment, and thus ignored, by the Guile interpreter.
Would it not be possible to generalize this method to any interpreter?
Second EDIT: After playing around a little bit, it seems that, for interpreters that can read their input from stdin, the following method would work:
#!/usr/bin/env sh
sed '1,2d' "$0" | bash --verbose --posix /dev/stdin; exit;
It's probably not optimal, though, as the sh process lives until the interpreter has finished its job. Any feedback or suggestion would be appreciated.
scripting environment-variables posix arguments shebang
edited Jun 21 at 11:13
asked Oct 22 '17 at 11:23
Rastapopoulos
518112
518112
1
Related: unix.stackexchange.com/questions/63979/â¦
â Kusalananda
Oct 22 '17 at 11:50
1
Also relevant: How to pass arguments to the shebang interpreter when executing a script?.
â Stephen Kitt
Oct 22 '17 at 11:54
add a comment |Â
1
Related: unix.stackexchange.com/questions/63979/â¦
â Kusalananda
Oct 22 '17 at 11:50
1
Also relevant: How to pass arguments to the shebang interpreter when executing a script?.
â Stephen Kitt
Oct 22 '17 at 11:54
1
1
Related: unix.stackexchange.com/questions/63979/â¦
â Kusalananda
Oct 22 '17 at 11:50
Related: unix.stackexchange.com/questions/63979/â¦
â Kusalananda
Oct 22 '17 at 11:50
1
1
Also relevant: How to pass arguments to the shebang interpreter when executing a script?.
â Stephen Kitt
Oct 22 '17 at 11:54
Also relevant: How to pass arguments to the shebang interpreter when executing a script?.
â Stephen Kitt
Oct 22 '17 at 11:54
add a comment |Â
4 Answers
4
active
oldest
votes
up vote
18
down vote
accepted
There is no general solution, at least not if you need to support Linux, because the Linux kernel treats everything following the first âÂÂwordâ in the shebang line as a single argument.
IâÂÂm not sure what NixOSâÂÂs constraints are, but typically I would just write your shebang as
#!/bin/bash --posix
or, where possible, set options in the script:
set -o posix
Alternatively, you can have the script restart itself with the appropriate shell invocation:
#!/bin/sh -
if [ "$1" != "--really" ]; then exec bash --posix -- "$0" --really "$@"; fi
shift
# Processing continues
This approach can be generalised to other languages, as long as you find a way for the first couple of lines (which are interpreted by the shell) to be ignored by the target language.
add a comment |Â
up vote
7
down vote
The shebang is described in execve(2) man page as follow:
#! interpreter [optional-arg]
Two spaces are accepted in this syntax:
- One space before the interpreter path, but this space is optional.
- One space separating the the interpreter path and its optional argument.
Note that I didn't used the plural when talking of an optional argument, neither does the syntax above uses [optional-arg ...], as you can provide at most one single argument.
As far as shell scripting is concerned, you can use the set built-in command near the beginning of your script which will allow to set interpreters parameters, providing the same result as if you used command-line arguments.
In your case:
set -o posix
From a Bash prompt, check the output of help set to get all available options.
1
YouâÂÂre allowed to have more than two spaces, theyâÂÂre just considered to be part of the optional argument.
â Stephen Kitt
Oct 22 '17 at 11:56
@StephenKitt: Indeed, white space here is to be taken more as a category than the actual space char. I suppose that other white spaces such as tabs should also be widely accepted.
â WhiteWinterWolf
Oct 22 '17 at 12:14
add a comment |Â
up vote
6
down vote
The POSIX standard is very terse on describing #!:
From the rationale section of the documentation of the exec() family of system interfaces:
Another way that some historical implementations handle shell scripts is by recognizing the first two bytes of the file as the character string
#!and using the remainder of the first line of the file as the name of the command interpreter to execute.
From the Shell Introduction section:
The shell reads its input from a file (see
sh), from the-coption or from thesystem()andpopen()functions defined in the System Interfaces volume of POSIX.1-2008. If the first line of a file of shell commands starts with the characters#!, the results are unspecified.
This basically means that any implementation (the Unix you are using) is free to do the specifics of the parsing of the shebang line as it wants.
Some Unices, like macOS (can't test ATM), will split the arguments given to the interpreter on the shebang line into separate arguments, while Linux and most other Unices will give the arguments as a single option to the interpreter.
It is thus unwise to rely on the shebang line being able to take more than a single argument.
See also the Portability section of the Shebang article on Wikipedia.
One easy solution, which is generalizable to any utility or language, is to make a wrapper script that executes the real script with the appropriate command line arguments:
#!/bin/sh
exec /bin/bash --posix /some/path/realscript "$@"
I don't think I would personally try to make it re-execute itself as that feels somewhat fragile.
add a comment |Â
up vote
2
down vote
On Linux, the shebang isn't very flexible; according to multiple answers (Stephen Kitt's answer and Jörg W Mittag's), there is no designated way to pass multiple arguments in a shebang line.
I'm not sure if it will be of use to anyone, but I've written a short script to implement the lacking feature. See https://pastebin.com/2dBEymat.
It is also possible to write embedded workarounds. Bellow, I present four language-agnostic workarounds applied to the same test script and the result each prints. I suppose that the script is executable and is in /tmp/shebang.
Wrapping your script in a bash heredoc inside process substitution
As far as I know, this is the most reliable language-agnostic way of doing it. It allows passing arguments and preserves stdin. The drawback is that the interpreter doesn't know the (real) location of the file it reads.
#!/bin/bash
exec python3 -O <(cat << EOWRAPPER
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
try:
print("input() 0 ::", input())
print("input() 1 ::", input())
except EOFError:
print("input() caused EOFError")
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
EOWRAPPER
) "$@"
Calling echo -e 'aanbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3 uses \escapes\' prints:
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /dev/fd/62
argv[1:] :: ['arg1', 'arg2 contains spaces', 'arg3\ uses\ \\escapes\\']
__debug__ :: False
PYTHON_SCRIPT_END
Note that process substitution produces a special file. This may not suit all executables. For instance, #!/usr/bin/less complains: /dev/fd/63 is not a regular file (use -f to see it)
I don't know if it is possible to have heredoc inside process substitution in dash.
Wrapping your script in a simple heredoc
Shorter and simpler, but you won't be able to access stdin from your script.
#!/bin/sh
exec python3 - "$@" << EOWRAPPER
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
try:
print("input() 0 ::", input())
print("input() 1 ::", input())
except EOFError:
print("input() caused EOFError")
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
EOWRAPPER
Calling echo -e 'aanbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3 uses \escapes\' prints:
PYTHON_SCRIPT_BEGINNING
input() caused EOFError
argv[0] :: -
argv[1:] :: ['arg1', 'arg2 contains spaces', 'arg3\ uses\ \\escapes\\']
__debug__ :: True
PYTHON_SCRIPT_END
Use awk system() call but without arguments
Correctly passes the name of the executed file, but your script won't receive the arguments you give it.
Note that awk is the only language I know whose interpreter both is installed on linux by default and reads its instructions from the command line by default.
#!/usr/bin/gawk BEGIN system("python3 -O " ARGV[1])
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
print("input() 0 ::", input())
print("input() 1 ::", input())
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
Calling echo -e 'aanbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3 uses \escapes\' prints:
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /tmp/shebang
argv[1:] ::
__debug__ :: False
PYTHON_SCRIPT_END
Use awk 4.1+ system() call, provided your arguments do not contain spaces
Nice, but only if you are sure your script won't be called with arguments containing spaces. As you can see, your arguments containing spaces would be split, unless the spaces are escaped.
#!/usr/bin/gawk @include "join"; BEGIN system("python3 -O " join(ARGV, 1, ARGC, " "))
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
print("input() 0 ::", input())
print("input() 1 ::", input())
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
Calling echo -e 'aanbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3 uses \escapes\' prints:
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /tmp/shebang
argv[1:] :: ['arg1', 'arg2', 'contains', 'spaces', 'arg3 uses \escapes\']
__debug__ :: False
PYTHON_SCRIPT_END
For awk versions below 4.1, you will have to use string concatenation inside a for loop, see example function https://www.gnu.org/software/gawk/manual/html_node/Join-Function.html .
add a comment |Â
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
18
down vote
accepted
There is no general solution, at least not if you need to support Linux, because the Linux kernel treats everything following the first âÂÂwordâ in the shebang line as a single argument.
IâÂÂm not sure what NixOSâÂÂs constraints are, but typically I would just write your shebang as
#!/bin/bash --posix
or, where possible, set options in the script:
set -o posix
Alternatively, you can have the script restart itself with the appropriate shell invocation:
#!/bin/sh -
if [ "$1" != "--really" ]; then exec bash --posix -- "$0" --really "$@"; fi
shift
# Processing continues
This approach can be generalised to other languages, as long as you find a way for the first couple of lines (which are interpreted by the shell) to be ignored by the target language.
add a comment |Â
up vote
18
down vote
accepted
There is no general solution, at least not if you need to support Linux, because the Linux kernel treats everything following the first âÂÂwordâ in the shebang line as a single argument.
IâÂÂm not sure what NixOSâÂÂs constraints are, but typically I would just write your shebang as
#!/bin/bash --posix
or, where possible, set options in the script:
set -o posix
Alternatively, you can have the script restart itself with the appropriate shell invocation:
#!/bin/sh -
if [ "$1" != "--really" ]; then exec bash --posix -- "$0" --really "$@"; fi
shift
# Processing continues
This approach can be generalised to other languages, as long as you find a way for the first couple of lines (which are interpreted by the shell) to be ignored by the target language.
add a comment |Â
up vote
18
down vote
accepted
up vote
18
down vote
accepted
There is no general solution, at least not if you need to support Linux, because the Linux kernel treats everything following the first âÂÂwordâ in the shebang line as a single argument.
IâÂÂm not sure what NixOSâÂÂs constraints are, but typically I would just write your shebang as
#!/bin/bash --posix
or, where possible, set options in the script:
set -o posix
Alternatively, you can have the script restart itself with the appropriate shell invocation:
#!/bin/sh -
if [ "$1" != "--really" ]; then exec bash --posix -- "$0" --really "$@"; fi
shift
# Processing continues
This approach can be generalised to other languages, as long as you find a way for the first couple of lines (which are interpreted by the shell) to be ignored by the target language.
There is no general solution, at least not if you need to support Linux, because the Linux kernel treats everything following the first âÂÂwordâ in the shebang line as a single argument.
IâÂÂm not sure what NixOSâÂÂs constraints are, but typically I would just write your shebang as
#!/bin/bash --posix
or, where possible, set options in the script:
set -o posix
Alternatively, you can have the script restart itself with the appropriate shell invocation:
#!/bin/sh -
if [ "$1" != "--really" ]; then exec bash --posix -- "$0" --really "$@"; fi
shift
# Processing continues
This approach can be generalised to other languages, as long as you find a way for the first couple of lines (which are interpreted by the shell) to be ignored by the target language.
edited Jun 21 at 11:46
Stéphane Chazelas
283k53521857
283k53521857
answered Oct 22 '17 at 11:55
Stephen Kitt
144k22313378
144k22313378
add a comment |Â
add a comment |Â
up vote
7
down vote
The shebang is described in execve(2) man page as follow:
#! interpreter [optional-arg]
Two spaces are accepted in this syntax:
- One space before the interpreter path, but this space is optional.
- One space separating the the interpreter path and its optional argument.
Note that I didn't used the plural when talking of an optional argument, neither does the syntax above uses [optional-arg ...], as you can provide at most one single argument.
As far as shell scripting is concerned, you can use the set built-in command near the beginning of your script which will allow to set interpreters parameters, providing the same result as if you used command-line arguments.
In your case:
set -o posix
From a Bash prompt, check the output of help set to get all available options.
1
YouâÂÂre allowed to have more than two spaces, theyâÂÂre just considered to be part of the optional argument.
â Stephen Kitt
Oct 22 '17 at 11:56
@StephenKitt: Indeed, white space here is to be taken more as a category than the actual space char. I suppose that other white spaces such as tabs should also be widely accepted.
â WhiteWinterWolf
Oct 22 '17 at 12:14
add a comment |Â
up vote
7
down vote
The shebang is described in execve(2) man page as follow:
#! interpreter [optional-arg]
Two spaces are accepted in this syntax:
- One space before the interpreter path, but this space is optional.
- One space separating the the interpreter path and its optional argument.
Note that I didn't used the plural when talking of an optional argument, neither does the syntax above uses [optional-arg ...], as you can provide at most one single argument.
As far as shell scripting is concerned, you can use the set built-in command near the beginning of your script which will allow to set interpreters parameters, providing the same result as if you used command-line arguments.
In your case:
set -o posix
From a Bash prompt, check the output of help set to get all available options.
1
YouâÂÂre allowed to have more than two spaces, theyâÂÂre just considered to be part of the optional argument.
â Stephen Kitt
Oct 22 '17 at 11:56
@StephenKitt: Indeed, white space here is to be taken more as a category than the actual space char. I suppose that other white spaces such as tabs should also be widely accepted.
â WhiteWinterWolf
Oct 22 '17 at 12:14
add a comment |Â
up vote
7
down vote
up vote
7
down vote
The shebang is described in execve(2) man page as follow:
#! interpreter [optional-arg]
Two spaces are accepted in this syntax:
- One space before the interpreter path, but this space is optional.
- One space separating the the interpreter path and its optional argument.
Note that I didn't used the plural when talking of an optional argument, neither does the syntax above uses [optional-arg ...], as you can provide at most one single argument.
As far as shell scripting is concerned, you can use the set built-in command near the beginning of your script which will allow to set interpreters parameters, providing the same result as if you used command-line arguments.
In your case:
set -o posix
From a Bash prompt, check the output of help set to get all available options.
The shebang is described in execve(2) man page as follow:
#! interpreter [optional-arg]
Two spaces are accepted in this syntax:
- One space before the interpreter path, but this space is optional.
- One space separating the the interpreter path and its optional argument.
Note that I didn't used the plural when talking of an optional argument, neither does the syntax above uses [optional-arg ...], as you can provide at most one single argument.
As far as shell scripting is concerned, you can use the set built-in command near the beginning of your script which will allow to set interpreters parameters, providing the same result as if you used command-line arguments.
In your case:
set -o posix
From a Bash prompt, check the output of help set to get all available options.
answered Oct 22 '17 at 11:51
WhiteWinterWolf
1,586830
1,586830
1
YouâÂÂre allowed to have more than two spaces, theyâÂÂre just considered to be part of the optional argument.
â Stephen Kitt
Oct 22 '17 at 11:56
@StephenKitt: Indeed, white space here is to be taken more as a category than the actual space char. I suppose that other white spaces such as tabs should also be widely accepted.
â WhiteWinterWolf
Oct 22 '17 at 12:14
add a comment |Â
1
YouâÂÂre allowed to have more than two spaces, theyâÂÂre just considered to be part of the optional argument.
â Stephen Kitt
Oct 22 '17 at 11:56
@StephenKitt: Indeed, white space here is to be taken more as a category than the actual space char. I suppose that other white spaces such as tabs should also be widely accepted.
â WhiteWinterWolf
Oct 22 '17 at 12:14
1
1
YouâÂÂre allowed to have more than two spaces, theyâÂÂre just considered to be part of the optional argument.
â Stephen Kitt
Oct 22 '17 at 11:56
YouâÂÂre allowed to have more than two spaces, theyâÂÂre just considered to be part of the optional argument.
â Stephen Kitt
Oct 22 '17 at 11:56
@StephenKitt: Indeed, white space here is to be taken more as a category than the actual space char. I suppose that other white spaces such as tabs should also be widely accepted.
â WhiteWinterWolf
Oct 22 '17 at 12:14
@StephenKitt: Indeed, white space here is to be taken more as a category than the actual space char. I suppose that other white spaces such as tabs should also be widely accepted.
â WhiteWinterWolf
Oct 22 '17 at 12:14
add a comment |Â
up vote
6
down vote
The POSIX standard is very terse on describing #!:
From the rationale section of the documentation of the exec() family of system interfaces:
Another way that some historical implementations handle shell scripts is by recognizing the first two bytes of the file as the character string
#!and using the remainder of the first line of the file as the name of the command interpreter to execute.
From the Shell Introduction section:
The shell reads its input from a file (see
sh), from the-coption or from thesystem()andpopen()functions defined in the System Interfaces volume of POSIX.1-2008. If the first line of a file of shell commands starts with the characters#!, the results are unspecified.
This basically means that any implementation (the Unix you are using) is free to do the specifics of the parsing of the shebang line as it wants.
Some Unices, like macOS (can't test ATM), will split the arguments given to the interpreter on the shebang line into separate arguments, while Linux and most other Unices will give the arguments as a single option to the interpreter.
It is thus unwise to rely on the shebang line being able to take more than a single argument.
See also the Portability section of the Shebang article on Wikipedia.
One easy solution, which is generalizable to any utility or language, is to make a wrapper script that executes the real script with the appropriate command line arguments:
#!/bin/sh
exec /bin/bash --posix /some/path/realscript "$@"
I don't think I would personally try to make it re-execute itself as that feels somewhat fragile.
add a comment |Â
up vote
6
down vote
The POSIX standard is very terse on describing #!:
From the rationale section of the documentation of the exec() family of system interfaces:
Another way that some historical implementations handle shell scripts is by recognizing the first two bytes of the file as the character string
#!and using the remainder of the first line of the file as the name of the command interpreter to execute.
From the Shell Introduction section:
The shell reads its input from a file (see
sh), from the-coption or from thesystem()andpopen()functions defined in the System Interfaces volume of POSIX.1-2008. If the first line of a file of shell commands starts with the characters#!, the results are unspecified.
This basically means that any implementation (the Unix you are using) is free to do the specifics of the parsing of the shebang line as it wants.
Some Unices, like macOS (can't test ATM), will split the arguments given to the interpreter on the shebang line into separate arguments, while Linux and most other Unices will give the arguments as a single option to the interpreter.
It is thus unwise to rely on the shebang line being able to take more than a single argument.
See also the Portability section of the Shebang article on Wikipedia.
One easy solution, which is generalizable to any utility or language, is to make a wrapper script that executes the real script with the appropriate command line arguments:
#!/bin/sh
exec /bin/bash --posix /some/path/realscript "$@"
I don't think I would personally try to make it re-execute itself as that feels somewhat fragile.
add a comment |Â
up vote
6
down vote
up vote
6
down vote
The POSIX standard is very terse on describing #!:
From the rationale section of the documentation of the exec() family of system interfaces:
Another way that some historical implementations handle shell scripts is by recognizing the first two bytes of the file as the character string
#!and using the remainder of the first line of the file as the name of the command interpreter to execute.
From the Shell Introduction section:
The shell reads its input from a file (see
sh), from the-coption or from thesystem()andpopen()functions defined in the System Interfaces volume of POSIX.1-2008. If the first line of a file of shell commands starts with the characters#!, the results are unspecified.
This basically means that any implementation (the Unix you are using) is free to do the specifics of the parsing of the shebang line as it wants.
Some Unices, like macOS (can't test ATM), will split the arguments given to the interpreter on the shebang line into separate arguments, while Linux and most other Unices will give the arguments as a single option to the interpreter.
It is thus unwise to rely on the shebang line being able to take more than a single argument.
See also the Portability section of the Shebang article on Wikipedia.
One easy solution, which is generalizable to any utility or language, is to make a wrapper script that executes the real script with the appropriate command line arguments:
#!/bin/sh
exec /bin/bash --posix /some/path/realscript "$@"
I don't think I would personally try to make it re-execute itself as that feels somewhat fragile.
The POSIX standard is very terse on describing #!:
From the rationale section of the documentation of the exec() family of system interfaces:
Another way that some historical implementations handle shell scripts is by recognizing the first two bytes of the file as the character string
#!and using the remainder of the first line of the file as the name of the command interpreter to execute.
From the Shell Introduction section:
The shell reads its input from a file (see
sh), from the-coption or from thesystem()andpopen()functions defined in the System Interfaces volume of POSIX.1-2008. If the first line of a file of shell commands starts with the characters#!, the results are unspecified.
This basically means that any implementation (the Unix you are using) is free to do the specifics of the parsing of the shebang line as it wants.
Some Unices, like macOS (can't test ATM), will split the arguments given to the interpreter on the shebang line into separate arguments, while Linux and most other Unices will give the arguments as a single option to the interpreter.
It is thus unwise to rely on the shebang line being able to take more than a single argument.
See also the Portability section of the Shebang article on Wikipedia.
One easy solution, which is generalizable to any utility or language, is to make a wrapper script that executes the real script with the appropriate command line arguments:
#!/bin/sh
exec /bin/bash --posix /some/path/realscript "$@"
I don't think I would personally try to make it re-execute itself as that feels somewhat fragile.
edited May 27 at 14:24
answered Oct 22 '17 at 12:06
Kusalananda
105k14209326
105k14209326
add a comment |Â
add a comment |Â
up vote
2
down vote
On Linux, the shebang isn't very flexible; according to multiple answers (Stephen Kitt's answer and Jörg W Mittag's), there is no designated way to pass multiple arguments in a shebang line.
I'm not sure if it will be of use to anyone, but I've written a short script to implement the lacking feature. See https://pastebin.com/2dBEymat.
It is also possible to write embedded workarounds. Bellow, I present four language-agnostic workarounds applied to the same test script and the result each prints. I suppose that the script is executable and is in /tmp/shebang.
Wrapping your script in a bash heredoc inside process substitution
As far as I know, this is the most reliable language-agnostic way of doing it. It allows passing arguments and preserves stdin. The drawback is that the interpreter doesn't know the (real) location of the file it reads.
#!/bin/bash
exec python3 -O <(cat << EOWRAPPER
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
try:
print("input() 0 ::", input())
print("input() 1 ::", input())
except EOFError:
print("input() caused EOFError")
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
EOWRAPPER
) "$@"
Calling echo -e 'aanbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3 uses \escapes\' prints:
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /dev/fd/62
argv[1:] :: ['arg1', 'arg2 contains spaces', 'arg3\ uses\ \\escapes\\']
__debug__ :: False
PYTHON_SCRIPT_END
Note that process substitution produces a special file. This may not suit all executables. For instance, #!/usr/bin/less complains: /dev/fd/63 is not a regular file (use -f to see it)
I don't know if it is possible to have heredoc inside process substitution in dash.
Wrapping your script in a simple heredoc
Shorter and simpler, but you won't be able to access stdin from your script.
#!/bin/sh
exec python3 - "$@" << EOWRAPPER
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
try:
print("input() 0 ::", input())
print("input() 1 ::", input())
except EOFError:
print("input() caused EOFError")
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
EOWRAPPER
Calling echo -e 'aanbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3 uses \escapes\' prints:
PYTHON_SCRIPT_BEGINNING
input() caused EOFError
argv[0] :: -
argv[1:] :: ['arg1', 'arg2 contains spaces', 'arg3\ uses\ \\escapes\\']
__debug__ :: True
PYTHON_SCRIPT_END
Use awk system() call but without arguments
Correctly passes the name of the executed file, but your script won't receive the arguments you give it.
Note that awk is the only language I know whose interpreter both is installed on linux by default and reads its instructions from the command line by default.
#!/usr/bin/gawk BEGIN system("python3 -O " ARGV[1])
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
print("input() 0 ::", input())
print("input() 1 ::", input())
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
Calling echo -e 'aanbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3 uses \escapes\' prints:
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /tmp/shebang
argv[1:] ::
__debug__ :: False
PYTHON_SCRIPT_END
Use awk 4.1+ system() call, provided your arguments do not contain spaces
Nice, but only if you are sure your script won't be called with arguments containing spaces. As you can see, your arguments containing spaces would be split, unless the spaces are escaped.
#!/usr/bin/gawk @include "join"; BEGIN system("python3 -O " join(ARGV, 1, ARGC, " "))
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
print("input() 0 ::", input())
print("input() 1 ::", input())
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
Calling echo -e 'aanbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3 uses \escapes\' prints:
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /tmp/shebang
argv[1:] :: ['arg1', 'arg2', 'contains', 'spaces', 'arg3 uses \escapes\']
__debug__ :: False
PYTHON_SCRIPT_END
For awk versions below 4.1, you will have to use string concatenation inside a for loop, see example function https://www.gnu.org/software/gawk/manual/html_node/Join-Function.html .
add a comment |Â
up vote
2
down vote
On Linux, the shebang isn't very flexible; according to multiple answers (Stephen Kitt's answer and Jörg W Mittag's), there is no designated way to pass multiple arguments in a shebang line.
I'm not sure if it will be of use to anyone, but I've written a short script to implement the lacking feature. See https://pastebin.com/2dBEymat.
It is also possible to write embedded workarounds. Bellow, I present four language-agnostic workarounds applied to the same test script and the result each prints. I suppose that the script is executable and is in /tmp/shebang.
Wrapping your script in a bash heredoc inside process substitution
As far as I know, this is the most reliable language-agnostic way of doing it. It allows passing arguments and preserves stdin. The drawback is that the interpreter doesn't know the (real) location of the file it reads.
#!/bin/bash
exec python3 -O <(cat << EOWRAPPER
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
try:
print("input() 0 ::", input())
print("input() 1 ::", input())
except EOFError:
print("input() caused EOFError")
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
EOWRAPPER
) "$@"
Calling echo -e 'aanbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3 uses \escapes\' prints:
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /dev/fd/62
argv[1:] :: ['arg1', 'arg2 contains spaces', 'arg3\ uses\ \\escapes\\']
__debug__ :: False
PYTHON_SCRIPT_END
Note that process substitution produces a special file. This may not suit all executables. For instance, #!/usr/bin/less complains: /dev/fd/63 is not a regular file (use -f to see it)
I don't know if it is possible to have heredoc inside process substitution in dash.
Wrapping your script in a simple heredoc
Shorter and simpler, but you won't be able to access stdin from your script.
#!/bin/sh
exec python3 - "$@" << EOWRAPPER
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
try:
print("input() 0 ::", input())
print("input() 1 ::", input())
except EOFError:
print("input() caused EOFError")
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
EOWRAPPER
Calling echo -e 'aanbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3 uses \escapes\' prints:
PYTHON_SCRIPT_BEGINNING
input() caused EOFError
argv[0] :: -
argv[1:] :: ['arg1', 'arg2 contains spaces', 'arg3\ uses\ \\escapes\\']
__debug__ :: True
PYTHON_SCRIPT_END
Use awk system() call but without arguments
Correctly passes the name of the executed file, but your script won't receive the arguments you give it.
Note that awk is the only language I know whose interpreter both is installed on linux by default and reads its instructions from the command line by default.
#!/usr/bin/gawk BEGIN system("python3 -O " ARGV[1])
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
print("input() 0 ::", input())
print("input() 1 ::", input())
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
Calling echo -e 'aanbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3 uses \escapes\' prints:
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /tmp/shebang
argv[1:] ::
__debug__ :: False
PYTHON_SCRIPT_END
Use awk 4.1+ system() call, provided your arguments do not contain spaces
Nice, but only if you are sure your script won't be called with arguments containing spaces. As you can see, your arguments containing spaces would be split, unless the spaces are escaped.
#!/usr/bin/gawk @include "join"; BEGIN system("python3 -O " join(ARGV, 1, ARGC, " "))
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
print("input() 0 ::", input())
print("input() 1 ::", input())
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
Calling echo -e 'aanbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3 uses \escapes\' prints:
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /tmp/shebang
argv[1:] :: ['arg1', 'arg2', 'contains', 'spaces', 'arg3 uses \escapes\']
__debug__ :: False
PYTHON_SCRIPT_END
For awk versions below 4.1, you will have to use string concatenation inside a for loop, see example function https://www.gnu.org/software/gawk/manual/html_node/Join-Function.html .
add a comment |Â
up vote
2
down vote
up vote
2
down vote
On Linux, the shebang isn't very flexible; according to multiple answers (Stephen Kitt's answer and Jörg W Mittag's), there is no designated way to pass multiple arguments in a shebang line.
I'm not sure if it will be of use to anyone, but I've written a short script to implement the lacking feature. See https://pastebin.com/2dBEymat.
It is also possible to write embedded workarounds. Bellow, I present four language-agnostic workarounds applied to the same test script and the result each prints. I suppose that the script is executable and is in /tmp/shebang.
Wrapping your script in a bash heredoc inside process substitution
As far as I know, this is the most reliable language-agnostic way of doing it. It allows passing arguments and preserves stdin. The drawback is that the interpreter doesn't know the (real) location of the file it reads.
#!/bin/bash
exec python3 -O <(cat << EOWRAPPER
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
try:
print("input() 0 ::", input())
print("input() 1 ::", input())
except EOFError:
print("input() caused EOFError")
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
EOWRAPPER
) "$@"
Calling echo -e 'aanbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3 uses \escapes\' prints:
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /dev/fd/62
argv[1:] :: ['arg1', 'arg2 contains spaces', 'arg3\ uses\ \\escapes\\']
__debug__ :: False
PYTHON_SCRIPT_END
Note that process substitution produces a special file. This may not suit all executables. For instance, #!/usr/bin/less complains: /dev/fd/63 is not a regular file (use -f to see it)
I don't know if it is possible to have heredoc inside process substitution in dash.
Wrapping your script in a simple heredoc
Shorter and simpler, but you won't be able to access stdin from your script.
#!/bin/sh
exec python3 - "$@" << EOWRAPPER
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
try:
print("input() 0 ::", input())
print("input() 1 ::", input())
except EOFError:
print("input() caused EOFError")
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
EOWRAPPER
Calling echo -e 'aanbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3 uses \escapes\' prints:
PYTHON_SCRIPT_BEGINNING
input() caused EOFError
argv[0] :: -
argv[1:] :: ['arg1', 'arg2 contains spaces', 'arg3\ uses\ \\escapes\\']
__debug__ :: True
PYTHON_SCRIPT_END
Use awk system() call but without arguments
Correctly passes the name of the executed file, but your script won't receive the arguments you give it.
Note that awk is the only language I know whose interpreter both is installed on linux by default and reads its instructions from the command line by default.
#!/usr/bin/gawk BEGIN system("python3 -O " ARGV[1])
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
print("input() 0 ::", input())
print("input() 1 ::", input())
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
Calling echo -e 'aanbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3 uses \escapes\' prints:
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /tmp/shebang
argv[1:] ::
__debug__ :: False
PYTHON_SCRIPT_END
Use awk 4.1+ system() call, provided your arguments do not contain spaces
Nice, but only if you are sure your script won't be called with arguments containing spaces. As you can see, your arguments containing spaces would be split, unless the spaces are escaped.
#!/usr/bin/gawk @include "join"; BEGIN system("python3 -O " join(ARGV, 1, ARGC, " "))
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
print("input() 0 ::", input())
print("input() 1 ::", input())
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
Calling echo -e 'aanbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3 uses \escapes\' prints:
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /tmp/shebang
argv[1:] :: ['arg1', 'arg2', 'contains', 'spaces', 'arg3 uses \escapes\']
__debug__ :: False
PYTHON_SCRIPT_END
For awk versions below 4.1, you will have to use string concatenation inside a for loop, see example function https://www.gnu.org/software/gawk/manual/html_node/Join-Function.html .
On Linux, the shebang isn't very flexible; according to multiple answers (Stephen Kitt's answer and Jörg W Mittag's), there is no designated way to pass multiple arguments in a shebang line.
I'm not sure if it will be of use to anyone, but I've written a short script to implement the lacking feature. See https://pastebin.com/2dBEymat.
It is also possible to write embedded workarounds. Bellow, I present four language-agnostic workarounds applied to the same test script and the result each prints. I suppose that the script is executable and is in /tmp/shebang.
Wrapping your script in a bash heredoc inside process substitution
As far as I know, this is the most reliable language-agnostic way of doing it. It allows passing arguments and preserves stdin. The drawback is that the interpreter doesn't know the (real) location of the file it reads.
#!/bin/bash
exec python3 -O <(cat << EOWRAPPER
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
try:
print("input() 0 ::", input())
print("input() 1 ::", input())
except EOFError:
print("input() caused EOFError")
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
EOWRAPPER
) "$@"
Calling echo -e 'aanbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3 uses \escapes\' prints:
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /dev/fd/62
argv[1:] :: ['arg1', 'arg2 contains spaces', 'arg3\ uses\ \\escapes\\']
__debug__ :: False
PYTHON_SCRIPT_END
Note that process substitution produces a special file. This may not suit all executables. For instance, #!/usr/bin/less complains: /dev/fd/63 is not a regular file (use -f to see it)
I don't know if it is possible to have heredoc inside process substitution in dash.
Wrapping your script in a simple heredoc
Shorter and simpler, but you won't be able to access stdin from your script.
#!/bin/sh
exec python3 - "$@" << EOWRAPPER
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
try:
print("input() 0 ::", input())
print("input() 1 ::", input())
except EOFError:
print("input() caused EOFError")
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
EOWRAPPER
Calling echo -e 'aanbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3 uses \escapes\' prints:
PYTHON_SCRIPT_BEGINNING
input() caused EOFError
argv[0] :: -
argv[1:] :: ['arg1', 'arg2 contains spaces', 'arg3\ uses\ \\escapes\\']
__debug__ :: True
PYTHON_SCRIPT_END
Use awk system() call but without arguments
Correctly passes the name of the executed file, but your script won't receive the arguments you give it.
Note that awk is the only language I know whose interpreter both is installed on linux by default and reads its instructions from the command line by default.
#!/usr/bin/gawk BEGIN system("python3 -O " ARGV[1])
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
print("input() 0 ::", input())
print("input() 1 ::", input())
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
Calling echo -e 'aanbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3 uses \escapes\' prints:
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /tmp/shebang
argv[1:] ::
__debug__ :: False
PYTHON_SCRIPT_END
Use awk 4.1+ system() call, provided your arguments do not contain spaces
Nice, but only if you are sure your script won't be called with arguments containing spaces. As you can see, your arguments containing spaces would be split, unless the spaces are escaped.
#!/usr/bin/gawk @include "join"; BEGIN system("python3 -O " join(ARGV, 1, ARGC, " "))
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
print("input() 0 ::", input())
print("input() 1 ::", input())
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
Calling echo -e 'aanbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3 uses \escapes\' prints:
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /tmp/shebang
argv[1:] :: ['arg1', 'arg2', 'contains', 'spaces', 'arg3 uses \escapes\']
__debug__ :: False
PYTHON_SCRIPT_END
For awk versions below 4.1, you will have to use string concatenation inside a for loop, see example function https://www.gnu.org/software/gawk/manual/html_node/Join-Function.html .
edited Jun 2 at 21:28
answered May 27 at 1:05
loxaxs
6341710
6341710
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f399690%2fmultiple-arguments-in-shebang%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
1
Related: unix.stackexchange.com/questions/63979/â¦
â Kusalananda
Oct 22 '17 at 11:50
1
Also relevant: How to pass arguments to the shebang interpreter when executing a script?.
â Stephen Kitt
Oct 22 '17 at 11:54