Mailinglist Archive: opensuse (818 mails)

< Previous Next >
RE: [opensuse] different types of shell scripts


-----Original Message-----
From: "George OLson" <grglsn765@xxxxxxxxx>
Sent: Thursday, September 22, 2011 4:11am
To: "suse" <opensuse@xxxxxxxxxxxx>
Subject: [opensuse] different types of shell scripts

I downloaded a program that I needed off the internet and the
installation program was a script file with the extension .sh. The
instructions from the developer said to run the script on a command line
by typing the command:

./<filename>

I thought (mistakenly) that I could run any shell script by typing the
command . <filename> (with a space between the dot and the filename). So
I tried to run it that way, and I got the error "cannot execute binary
file".

However, when I followed the developer's instructions and typed in
./<filename>, the script executed perfectly and installed the program.

So my question is, what is the difference between running a script file
with the command

<dot><space><filename>, for example "#> . myscript.sh"

and running it with

<dot><slash><filename>, for example "#> ./myscript.sh"?


dot-space-filename means to source the file not run it.

When you run a file you spawn a new process and execute the file in that
process. For shell scripts an extra step happens in that the specified script
is not executed, the appropriate interpreter is executed, and THAT then reads
the specified script. At the end that child process and all it's environment
dies and goes away. The parent process is on hold in the background during
that, and resumes where it left off, unaffected by anything the child process
did other than knowing the child processes exit value.

Sourcing a file is quite different.

When you source a file, no child process if spawned. The current process
directly reads and (tries to) interpret the files contents the same as if you
had typed in the same lines manually at your shell prompt. If there is an exit
command in the file, your currently running shell will exit and your xterm
window will close or you'll be logged out of your ssh session etc. Any
environment variables that get set or changed in the file will still be set in
your environment after the file is done. If there was a cd command, you'll
still be sitting wherever the file cd'd to.

Basically, it's almost never correct to source files manually at interactive
command prompts. Ok there are theoretical situations where you might
intentionally want to do that, but, generally no.

The purpose of the sourcing mechanism is to allow a script to include chunks of
modular code and configuration settings from other files instead of having to
include everything inside the script itself. It allows you to have a script in
/sbin that's the same on all boxes like a binary, yet have site-specific config
variables in /etc or even personal config variables in /home, and a single copy
of library functions in /lib that multiple different scripts all use instead of
each script having to have a copy inside themselves.

Also, sourcing only works if the file being sourced is even valid language for
the interpreter you happen to be running at the time.

Inside a script, the script author knows that the file he's sourcing IS valid
script in the same language as the parent script. When you're logged in to a
command prompt, you're running bash, but any random file you need to run might
be written in anything. It might contain perfectly good perl syntax that might
result in bash overwriting files just by having a ">" somewhere for instance.
Even if you only ever did that for *.sh files, you still have the environment
problem. Poorly written scripts don't bother establishing their own environment
at the start, and don't bother using the exit command to set meaningful exit
values, and so you can often get away with sourcing poorly written scripts and
your current shell process runs the included commands and seems to all work
fine. But if a properly written script had say, some error detection in it
where it used the exit command to set an exit value that the parent script can
read, the exit command in the script will actually log you all the way out of
your xterm or ssh session on the spot.

--
bkw


--
To unsubscribe, e-mail: opensuse+unsubscribe@xxxxxxxxxxxx
For additional commands, e-mail: opensuse+help@xxxxxxxxxxxx

< Previous Next >
Follow Ups
References