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



Relevant Pages