I know it, forget it and relearn it
again. Time to write it down.
Friday 15 December 2017
linux - How to run a shell script on a Unix console or Mac terminal?
To run a
non-executable sh
script,
use:
sh
myscript
To
run a non-executable bash
script,
use:
bash
myscript
To start an
executable (which is any file with executable permission); you just specify it by its
path:
/foo/bar
/bin/bar
./bar
To
make a script executable, give it the necessary
permission:
chmod +x
bar
./bar
When
a file is executable, the kernel is responsible for
figuring out how to execte it. For non-binaries, this is done by looking at the first
line of the file. It should contain a
hashbang
:
#!
/usr/bin/env bash
The
hashbang tells the kernel what program to run (in this case the command
/usr/bin/env
is ran with the argument
bash
). Then, the script is passed to the program (as second
argument) along with all the arguments you gave the script as subsequent
arguments.
That means every script
that is executable should have a hashbang. If it doesn't, you're not
telling the kernel what it is, and therefore the kernel doesn't
know what program to use to interprete it. It could be bash
,
perl
, python
,
sh
, or something else. (In reality, the kernel will often use
the user's default shell to interprete the file, which is very dangerous because it
might not be the right interpreter at all or it might be able to parse some of it but
with subtle behavioural differences such as is the case between
sh
and
bash
).
Most
commonly, you'll see hash bangs like
so:
#!/bin/bash
The
result is that the kernel will run the program /bin/bash
to
interpret the script. Unfortunately, bash
is not always shipped
by default, and it is not always available in /bin
. While on
Linux machines it usually is, there are a range of other POSIX machines where
bash
ships in various locations, such as
/usr/xpg/bin/bash
or
/usr/local/bin/bash
.
To
write a portable bash script, we can therefore not rely on hard-coding the location of
the bash
program. POSIX already has a mechanism for dealing
with that: PATH
. The idea is that you install your programs in
one of the directories that are in PATH
and the system should
be able to find your program when you want to run it by
name.
Sadly, you
cannot just do
this:
#!bash
The
kernel won't (some might) do a PATH
search for you. There is a
program that can do a PATH
search for you, though, it's called
env
. Luckily, nearly all systems have an
env
program installed in /usr/bin
. So
we start env
using a hardcoded path, which then does a
PATH
search for bash
and runs it so
that it can interpret your
script:
#!/usr/bin/env
bash
This
approach has one downside: According to POSIX, the hashbang can have one
argument. In this case, we use bash
as the
argument to the env
program. That means we have no space left
to pass arguments to bash
. So there's no way to convert
something like #!/bin/bash -exu
to this scheme. You'll have to
put set -exu
after the hashbang
instead.
This approach also has another
advantage: Some systems may ship with a /bin/bash
, but the user
may not like it, may find it's buggy or outdated, and may have installed his own
bash
somewhere else. This is often the case on OS X (Macs)
where Apple ships an outdated /bin/bash
and users install an
up-to-date /usr/local/bin/bash
using something like Homebrew.
When you use the env
approach which does a
PATH
search, you take the user's preference into account and
use his preferred bash over the one his system shipped with.
php - file_get_contents shows unexpected output while reading a file
I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print &q...
-
I have an app which needs a login and a registration with SQLite. I have the database and a user can login and register. But i would like th...
-
I got an error in my Java program. I think this happens because of the constructor is not intialized properly. My Base class Program public ...
-
I would like to use enhanced REP MOVSB (ERMSB) to get a high bandwidth for a custom memcpy . ERMSB was introduced with the Ivy Bridge micro...
No comments:
Post a Comment