I always forget about how to use shell environment variable correctly. I think because I did not grasp the key concept. For example, here is the wrong approach:
1
2
$ FOO=foo BAR=bar echo foo is ${FOO} and bar is ${BAR}
foo is and bar is
The correct answer I was hoping for is:
1
foo is foo and bar is bar
Because what I frequently do is use environment variable inside shell script:
1
2
3
4
5
#!/usr/bin/env bash
#
# script.sh
echo foo is ${FOO} and bar is ${BAR}
then do:
1
2
$ FOO=foo BAR=bar ./script.sh
foo is foo and bar is bar
This works as expected because the environment variables are passed into the subshell that executing the script.
But why not the first or the wrong approach?
The reason is that shell expands the variable before the command being executed. To shell, the first approach looks like:
1
$ FOO=foo BAR=bar echo foo is and bar is
The environment variables FOO and BAR were expanded before the command was executed. Hence, no values were printed.
To build Redis from source, we first need to install TCL 8.5 or newer, this is needed for make test later:
$ sudo apt-get install -ytcl
Now clone and make:
$ git clone https://github.com/antirez/redis
$ git checkout 2.8.13
$ make
$ make test
$ sudo make install
$ sudo utils/install_server.sh
Binary (redis-cli and redis-server) will be installed into /usr/local/bin.
The last command with utils/install_server.sh is an interactive command. Since the script is a shell script using the read built-in command and -p option for prompt, we can make it non-interactive by redirecting input from echo command:
$ echo -n | sudo utils/install_server.sh
Without pumping any value into the script, the default values are used.
If really want to customize it, we can add our own values:
Frequently the initial two characters on the initial line of a script are: #!.
Why Shebang? Well, simple reason, because shell needs to know which interpreter to use when executing the script.
The sha-bang (#!) at the head of a script tells your system that this file is a set of commands to be fed to the command interpreter indicated. The #! is actually a two-byte magic number, a special marker that designates a file type, or in this case an executable shell script (type man magic for more details on this fascinating topic). Immediately following the sha-bang is a path name. This is the path to the program that interprets the commands in the script, whether it be a shell, a programming language, or a utility. This command interpreter then executes the commands in the script, starting at the top (the line following the sha-bang line), and ignoring comments. - Starting Off With a Sha-Bang
The shebang line is usually ignored by the interpreter because the # character is a comment marker in many scripting languages. Even the actual script is written with a different commenting character, such as in JavaScript:
1
2
#!/usr/bin/env node
// JavaScript stuff starts here.
Because the first line is interpreted by the shell, and the rest is passed into JavaScript interpreter, in this case, Node.
The syntax of shebang:
#! interpreter [optional-arg]
Whether there is a space between shebang character and the interpreter or not, it does not matter.
The interpreter must usually be an absolute path to a program that is not itself a script. The following are example interpreters:
1
2
#! /bin/sh
#! /bin/bash
More examples are via head -n 1 /etc/init.d/*.
The optional‑arg should either not be included or it should be a string that is meant to be a single argument (for reasons of portability, it should not contain any whitespace). - Shebang_(Unix)
We also frequently see the following shebang:
1
#!/usr/bin/env bash
That has to do with portability. Not every system install node or bash command in the same path. /usr/bin/env will search through user’s $PATH, and correctly locate the executable.
To conclude for Node, here is the format I am using: