Shell scripts are interpreted as opposed to executed. A C program when compiled produces a (binary) file which contains instructions to be fed to the CPU. But a shell script, or a Perl script do not contain instructions for the CPU. They are written in a higher level language which someone = the interpreter must interpret to the language the CPU understands.
If your higher level language is Perl then this interpreter must be /usr/bin/perl. This is why when you have a Perl program a.pl you execute it in one of two ways:
In (2), I say "execute" in quotes because the shell you are running in will understand that this file a.pl contains no CPU language and will try to find an interpreter for it. The first thing to try will be to read the first line and check if it starts with #!. If it does then it will use the rest of the line as the actual interpreter of the rest of the file contents. In the case of a.pl, yes it starts with #! and so the interpreter will be what follows, i.e. /usr/bin/perl. And will run it as case #1.
However what happens if no #! is found in the first line?
In this case there are other obscure and arcane heuristics probably different to different shells (bash, sh, csh, ksh, zsh, gosh they are a lot!) to find an interpreter somewhere. YOU DO NOT WANT THAT if you are serious. It is best to be explicit about who your interpreter must be and tell that to the shell either via feeding your program directly into the interpreter (case 1) or via the shebang (case 2).
source is a special shell built-in directive, at least for bash, sh, csh. i.e. there is no executable file associated with it. You will never find a file called /bin/source. Try it: find / -type f -executable -name 'source' So, source is a shell construct, a directive like a for, if etc. What does it do? It interprets the contents of the file fed with and places the results in the current shell without spawning a new shell. This does not affect your program output like your echo statements but it affects setting environment variables and changing directories, among other things.
For example spot the different between "executing" the following program either with source (source a.bash) or with a shebang (./a.bash):
#!/bin/bash # file a.bash export A=12 cd / echo my PWD=$PWD
In the first case echo $A will output 12 and you will find that you changed dir to the root. In the second case A will be undefined and your current dir will be the one you were in before you run it.
All these within the current shell you are running in (e.g. bash).
Now, you want to run shell scripts within perl. Here is a question for you: in your examples, which shell perl will spawn in order to pass it your shell script for interpretation? If you do not know the answer then my advice, for what is worth, is to proceed no further without finding it. Because you will be having your shell scripts interpreted by an interpreter you do not know. Introducing uncertainty in your programs, especially if they will be run in different environments, is not a good idea unless you want to spread chaos, unleash forces you do not understand about, have hospital equipment failing, helicopters falling down from the sky, nuclear rockets released by themselves, contraceptive devices acting like a swiss cheese, you get the idea...
Some readers' eyes must have caught haj's and haukex's use of bash -c and /bin/bash. They are being explicit about the shell they want to use to interpret their shell scripts. This is the right way. Be explicit about your shells interpreters.
In reply to Re: system & exec
by bliako
in thread system & exec
by dideod.yang
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |