Mailinglist Archive: opensuse (818 mails)

< Previous Next >
Re: [opensuse] different types of shell scripts
On 09/23/2011 02:02 AM, brian@xxxxxxxxx wrote:


-----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 lo
g you all the way out of your xterm or ssh session on the spot.


Thanks for taking the time to write all that. That is a really good explanation, and is now very helpful as I learn more about writing scripts.

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

< Previous Next >
Follow Ups
References