[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"? G -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
On Thu, 2011-09-22 at 16:11 +0800, George OLson wrote:
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 would do this: chmod +x filename.sh ./filename.sh Of course, only if I trust the source. And hopefully not as root. Yours sincerely, Roger Oberholtzer OPQ Systems / Ramböll RST Office: Int +46 10-615 60 20 Mobile: Int +46 70-815 1696 roger.oberholtzer@ramboll.se ________________________________________ Ramböll Sverige AB Krukmakargatan 21 P.O. Box 17009 SE-104 62 Stockholm, Sweden www.rambollrst.se -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
Le 22/09/2011 10:26, Roger Oberholtzer a écrit :
I would do this:
chmod +x filename.sh ./filename.sh
by the way, for a shell script, simply use "sh ./filename" jdd -- http://www.dodin.net http://pizzanetti.fr -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
On Thu, 2011-09-22 at 10:40 +0200, jdd wrote:
Le 22/09/2011 10:26, Roger Oberholtzer a écrit :
I would do this:
chmod +x filename.sh ./filename.sh
by the way, for a shell script, simply use "sh ./filename"
Of course that works. OTOH, if the script starts with, say, #!python then your method runs an additional unneeded shell to run python. Of course, the problem with my method is it assumes that there is a #!some-interpreter on the first line. So, the very first thing to do is to look at the first line of the script. It it has a #!shell-something, then I prefer my method. Otherwise, you need to verify what shell it is written for and then envoke that as required.
jdd
Yours sincerely, Roger Oberholtzer OPQ Systems / Ramböll RST Office: Int +46 10-615 60 20 Mobile: Int +46 70-815 1696 roger.oberholtzer@ramboll.se ________________________________________ Ramböll Sverige AB Krukmakargatan 21 P.O. Box 17009 SE-104 62 Stockholm, Sweden www.rambollrst.se -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
Le 22/09/2011 13:20, Roger Oberholtzer a écrit :
On Thu, 2011-09-22 at 10:40 +0200, jdd wrote:
chmod +x filename.sh
./filename.sh
by the way, for a shell script, simply use "sh ./filename"
Of course that works. OTOH, if the script starts with, say,
#!python
if a filename.sh script runs python, it's pretty badly named :-) jdd -- http://www.dodin.net http://pizzanetti.fr -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
On Thu, 2011-09-22 at 14:02 +0200, jdd wrote:
Le 22/09/2011 13:20, Roger Oberholtzer a écrit :
On Thu, 2011-09-22 at 10:40 +0200, jdd wrote:
chmod +x filename.sh
./filename.sh
by the way, for a shell script, simply use "sh ./filename"
Of course that works. OTOH, if the script starts with, say,
#!python
if a filename.sh script runs python, it's pretty badly named :-)
I was thinking in more general terms. Nonetheless, one should be careful of scripts pulled off the 'net. The name and the contents may not match. Yours sincerely, Roger Oberholtzer OPQ Systems / Ramböll RST Office: Int +46 10-615 60 20 Mobile: Int +46 70-815 1696 roger.oberholtzer@ramboll.se ________________________________________ Ramböll Sverige AB Krukmakargatan 21 P.O. Box 17009 SE-104 62 Stockholm, Sweden www.rambollrst.se -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Thursday, 2011-09-22 at 16:11 +0800, George OLson wrote:
<dot><slash><filename>, for example "#> ./myscript.sh"?
This is done to run a file that is not in the PATH. The other method I do not know. - -- Cheers, Carlos E. R. (from 11.4 x86_64 "Celadon" at Telcontar) -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.16 (GNU/Linux) iEYEARECAAYFAk568uwACgkQtTMYHG2NR9Vb9ACeN37NZd48sVdVYcTwQzBQn1nF LN0Anisnbpr53NVNc4CkWSzPYNAYEZWj =X3Rm -----END PGP SIGNATURE----- -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
Le 22/09/2011 10:11, George OLson a écrit :
So my question is, what is the difference between running a script file with the command
<dot><space><filename>, for example "#> . myscript.sh"
......................... "help ." .: . filename [arguments] Execute commands from a file in the current shell. Read and execute commands from FILENAME in the current shell. The entries in $PATH are used to find the directory containing FILENAME. If any ARGUMENTS are supplied, they become the positional parameters when FILENAME is executed. Exit Status: Returns the status of the last command executed in FILENAME; fails if FILENAME cannot be read. so . filename runs the script listed in the file filename .......................... usually, "." is the current folder, so ./script runs the script in the current folder, just in case you have a widely executable of the same name for example, test is a shel command, so: dd@linux-0i5h:~> test jdd@linux-0i5h:~> ./test bash: ./test: Aucun fichier ou dossier de ce type with ./test I could run my own script named test (just a example, it's not a good idea to have several commands with different result) jdd -- http://www.dodin.net http://pizzanetti.fr -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
Le 22/09/2011 10:39, jdd a écrit : I should have put the dots before this line
so . filename runs the script listed in the file filename ..........................
and reading again using ". filename" seems mostly the same as running "filename" alone jdd -- http://www.dodin.net http://pizzanetti.fr -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
On 22/09/11 10:42, jdd wrote:
Le 22/09/2011 10:39, jdd a écrit : I should have put the dots before this line
so . filename runs the script listed in the file filename ..........................
and reading again using ". filename" seems mostly the same as running "filename" alone
I've come across this using easy-rsa in openvpn it uses ".<space>filename" to use the file to set up system variables INSTALL Instructions 1. Edit vars. 2.3.4. 5 . vars 6. ./clean-all DC -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 2011-09-22 10:42, jdd wrote:
and reading again using ". filename" seems mostly the same as running "filename" alone
It was done inside scripts to load environment variables from another script. Ie, it reuses the same shell, makes sense. - -- Cheers / Saludos, Carlos E. R. (from 11.4 x86_64 "Celadon" at Telcontar) -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.16 (GNU/Linux) Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org/ iEYEARECAAYFAk569mYACgkQtTMYHG2NR9XSyACgjrYtY+heaLDgiHnu7IuHxhIR 5rEAn0HpPsNsYgEXLeRZn2DFaYw1GfVK =7aQD -----END PGP SIGNATURE----- -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
On Thu, 2011-09-22 at 10:48 +0200, Carlos E. R. wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 2011-09-22 10:42, jdd wrote:
and reading again using ". filename" seems mostly the same as running "filename" alone
It was done inside scripts to load environment variables from another script. Ie, it reuses the same shell, makes sense.
Not really. If the script changes, say, the PATH, it will then be changed for your shell as well. You may also wind up in some other place when it is done. Sourcing a script should only be done if the script is intended specifically for this purpose. I would never do this to a script that installs software. Yours sincerely, Roger Oberholtzer OPQ Systems / Ramböll RST Office: Int +46 10-615 60 20 Mobile: Int +46 70-815 1696 roger.oberholtzer@ramboll.se ________________________________________ Ramböll Sverige AB Krukmakargatan 21 P.O. Box 17009 SE-104 62 Stockholm, Sweden www.rambollrst.se -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
Roger Oberholtzer said the following on 09/22/2011 07:22 AM:
Not really. If the script changes, say, the PATH, it will then be changed for your shell as well. You may also wind up in some other place when it is done.
A very good point. This is why you should always run as sub-processes of the command line. Its reasonable for a sub-process script to source something. We can see lots of examples of the in /etc/init.d/* All perfectly valid because they run as sub-processes so don't affect the calling process.
Sourcing a script should only be done if the script is intended specifically for this purpose.
Such as .profile (and variants)
I would never do this to a script that installs software.
Quite! In fact I'd never do it with a script that I hadn't audited to be sure it wasn't going to do odd things to my environment; which means be very careful when running externally supplied code as root. -- We succeed only as we identify in life, or in war, or in anything else, a single overriding objective, and make all other considerations bend to that one objective. Dwight D. Eisenhower, speech, April 2, 1957 -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
jdd said the following on 09/22/2011 04:39 AM:
Le 22/09/2011 10:11, George OLson a écrit :
So my question is, what is the difference between running a script file with the command
<dot><space><filename>, for example "#> . myscript.sh"
......................... "help ."
.: . filename [arguments] Execute commands from a file in the current shell.
This is normally called 'sourcing'. On the whole it is NOT a sensible practice for _executing_ a script. It use is normally to set parameters. For example, you will see in /etc/init.d/ files that are part of the RC, that are linked into /etc/rc3.d and /etc/rc5.d and so on. In these files you will see lines such as: . /etc/rc.status . /etc/sysconfig/sound . /etc/sysconfig/boot This 'execute' the setting of shell/environment variables. This is a healthy/"Good Practice" use of 'sourcing'. Its not the only one. Your .profile and the base and X11 equivalents do a similar thing and they may also actually execute external programs, set things running in the background (such as ssh-agent). What they are not doing, and what I would consider BAD PRACTICE is running in the current shell things that should be run in a sub-shell or sub-process. Back when, UNIX started something radically different that we now consider the norm. Back when, processes were deemed expensive to create so they weren't. The CLI just ran one program at a time, had not control flow. There was a "Transient Program Area" and the CLI caused the executive to overlay the CLI with the application. Great for what were single process systems like CPM/DOS and their mainframe predecessors. When the application terminated the system somehow reloaded the CLI and you were off again. What made UNIX radical was that the CLI, the shell, stuck around; process creation was cheap an easy and so the application was run in a sub-process. That meant the CLI could do things that weren't possible before. It could run a sequence of programs; it could run two (or more) child processes that were connected via pipe. We take this for granted now, but back in the 70s and 80s this was radical. many people who had grown up with mainframe and mini OSes simply could not get their head around this. The idea of the CLI as a programming language was beyond them. I am not joking. I saw this persist into the 1980s. I worked at an establishment where I put up "Software Tools" on the VAX/VMS that I was using (UGH! FORTRAN!) and things really moved. My peers and managers didn't understand what the fuss was and in the end did not appreciate that I was (at least) 5 times as productive because I had suitable tools. Realistically, its not just having the tools; they were there on the VAX for anyone to use. It is knowing how to use them and use them appropriately. I did; the people who saw VAX/VMS and the CLI and TPA model, processes being 'expensive' so run everything in the one 'shell', couldn't alter their thinking to the 'tools' and throwaway process ("grep for something....", "use sed to transform a file") mode of thinking. Not so much dinosaurs as snails. You can see examples of appropriate use in the various shell scripts on the system. Back when, the PDP-11 days, version 6, 7, PDP-11s, small address spaces, small disks, script were used a LOT more than they are today. Pretty much out of necessity. -- Leadership is understanding people and involving them to help you do a job. That takes all of the good characteristics, like integrity, dedication of purpose, selflessness, knowledge, skill, implacability, as well as determination not to accept failure. ~ Admiral Arleigh A. Burke -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
Anton Aylward wrote:
Back when, UNIX started something radically different that we now consider the norm. Back when, processes were deemed expensive to create so they weren't. The CLI just ran one program at a time, had not control flow. There was a "Transient Program Area" and the CLI caused the executive to overlay the CLI with the application. Great for what were single process systems like CPM/DOS and their mainframe predecessors. When the application terminated the system somehow reloaded the CLI and you were off again.
What made UNIX radical was that the CLI, the shell, stuck around; process creation was cheap an easy and so the application was run in a sub-process. That meant the CLI could do things that weren't possible before. It could run a sequence of programs; it could run two (or more) child processes that were connected via pipe.
We take this for granted now, but back in the 70s and 80s this was radical.
Hmm, UNIX was first named UNICS, named after MULTICS, from which it took many features, including multiprocessing. As well as MULTICS, the Burroughs MCP had parallel execution of tasks, as did ICL's GEORGE 3. They all had job control languages too, and all in the 1960s before Unix was conceived. The history of computing contains a lot of reinventions of the wheel, as new people join the party or new types of hardware are built. Virtual memory and filestores are another area where it feels like groundhog day. -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
Dave Howorth said the following on 09/22/2011 10:07 AM:
Hmm, UNIX was first named UNICS, named after MULTICS, from which it took many features, including multiprocessing. As well as MULTICS, the Burroughs MCP had parallel execution of tasks, as did ICL's GEORGE 3. They all had job control languages too, and all in the 1960s before Unix was conceived.
I've used Burroughs engines and George on a 1901/2. Saying "job control language" is still not a 'shell' in the way Steve Bourne (another Brit) conceived of it. They were still line-oriented. When they had decision/branching statements they were "interpreted" line by line, often be re-reading the file so they could GOTO a previous statement. Yes, I know, I worked on the code! What made Steve's shell different was that he read in and tokenized the whole file (then closed it and forget about the source). Was this new? No; you can be anything in the computer field had already been pioneered at Manchester or Cambridge :-) In fact it was Professor Peter J Brown or Cambridge, later at UKC, http://www.cs.kent.ac.uk/news/2007/PeterBrown/ who published a lot on what were termed "throwaway interpreters"; he worked on them in 60s and 70s. Once PJB game me an exercise. It was core-dump of the internal store for a throwaway compiler. I had to reverse engineer its format and work out what the OPCODEs were and create a new (even if very simple) program. We then used a core manipulation language to 'load' it an see if it would run. YAH! It worked! All that was on a 1901. Yes, I know web pages say "2900 series" but this was before the 2900 was installed. Then and only then did he let us at the UNIX Release 5 machines ... PJB was a great guy to work with and study with :-) I still have his books; they are examples of clear writing. http://en.wikipedia.org/wiki/Hypertext#History <quote> Guide, the first significant hypertext system for personal computers, was developed by Peter J. Brown at UKC in 1982. </quote>
The history of computing contains a lot of reinventions of the wheel, as new people join the party or new types of hardware are built. Virtual memory and filestores are another area where it feels like groundhog day.
My current gripe is about NoSQL - and all the people who don't understand why we gave up on the NoSQL databases and moved to SQL in the 80s. Say CODASYL to these people, say ISAM, say IDS, say IMS (or other high performance database systems) ... they don't know what you are talking about, but they are wetting themselves demanding NoSQL. -- "Key escrow to rule them all; key escrow to find them. Key escrow to bring them all and in the darkness bind them. In the land of surveillance where Big Brother lies." -- Peter Gutmann -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
Anton Aylward wrote:
Dave Howorth said the following on 09/22/2011 10:07 AM:
Sorry for the late reply. It's taken a while to read some stuff.
Hmm, UNIX was first named UNICS, named after MULTICS, from which it took many features, including multiprocessing. As well as MULTICS, the Burroughs MCP had parallel execution of tasks, as did ICL's GEORGE 3. They all had job control languages too, and all in the 1960s before Unix was conceived.
I've used Burroughs engines and George on a 1901/2. Saying "job control language" is still not a 'shell' in the way Steve Bourne (another Brit) conceived of it. They were still line-oriented.
Well the shell is still line oriented :)
When they had decision/branching statements they were "interpreted" line by line, often be re-reading the file so they could GOTO a previous statement. Yes, I know, I worked on the code!
What made Steve's shell different was that he read in and tokenized the whole file (then closed it and forget about the source). Was this new?
How interpretive languages are interpreted is an interesting and important subject, but I don't think it is fundamental in defining a modern shell. There's an interesting paper describing "GEORGE 3 — A general purpose time sharing and operating system", which was written in 1967 and is available at http://dl.acm.org/citation.cfm?id=363806 It describes the following features of the GEORGE3 JCL, which was based on CTSS command language from project Mac: - same language for users at terminals & batch jobs; - job/process forking and reconnection, and suspension waiting for events; - equivalence of job scripts in files, binary programs and system commands - recursion within scripts - device/file independence and shell i/o redirection - exception traps It also describes the filestore: - sequential & random access files - automatic offlining/backup and recovery (multi-level infinite filestore) - pipes ('communication files') - hierarchical directory tree - relative and absolute paths - home directories - symlinks - 'streams' - virtual files made by concatenating other files - read, write, execute & append permissions - separate permissions for owners, other users and groups I don't think there's a lot missing there from most shells. Cheers, Dave -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
On Thu, 22 Sep 2011 16:11:03 +0800, George OLson <grglsn765@gmail.com> wrote:
<dot><space><filename>, for example "#> . myscript.sh"
That runs a given shell in the context of the current shell, i.e. no child process is created.
<dot><slash><filename>, for example "#> ./myscript.sh"?
This means "run the script myscript.sh in the current directory. The './' is needed for the user root as he doesn't have the current directory in his search path for executable code (set via the environment variable PATH) as that would make it easy to trick him into executing dubious code that just happens to have the name of a common command. As a normal user it only speeds up starting the script as then the shell doesn't have to search PATH. hth Philipp -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
Hello, On Thu, 22 Sep 2011, George OLson wrote:
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"?
The main difference in this context is the value of $0. As other's wrote, '.' "sources" the script in the current shell, thus, $0 stays as it were: $ echo 'echo $0' | . /dev/stdin bash Calling a script via sh PATH/file or make PATH/file executable and then call PATH/file (where PATH may be '.'), then, $0 gets set to the name of the _scriptfile_: $ echo 'echo $0' >/tmp/t.sh $ sh /tmp/t.sh /tmp/t.sh $ chmod 700 /tmp/t.sh $ /tmp/t.sh /tmp/t.sh And, surprise surprise, self-extracting archives (shar and the like) have a shell-script at the top and then reread themselves with an offset (with e.g. dd) to extract the actual archive (usually a tar). So, basically what those script do is: dd if=$0 skip=... | tar x ... And if $0 is not the name of the script/archive but /bin/bash, go figure. What exactly caused the error you got when using '. file' I don't know, but it's likely to be a side-effect of the above mentioned. HTH, -dhn -- "Recently a friend gave me a pornographic video and said that I'd like it, but I don't know how to watch it. I don't have a pornograph." -- Peter Moylan in alt.usage.english -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
On 09/22/2011 04:11 AM, George OLson pecked at the keyboard and wrote:
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"
Used to source the contents of the file, typically used when changes are made to your .bashrc file (or other file containing environment variables) so that you do not need to log out/in to read the changes into your current login session.
and running it with
<dot><slash><filename>, for example "#> ./myscript.sh"?
Used to execute the shell script, better to use "sh myscript.sh" (without the quotes).
G
-- Ken Schneider SuSe since Version 5.2, June 1998 -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
-----Original Message----- From: "George OLson" <grglsn765@gmail.com> Sent: Thursday, September 22, 2011 4:11am To: "suse" <opensuse@opensuse.org> 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@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
On 09/23/2011 02:02 AM, brian@aljex.com wrote:
-----Original Message----- From: "George OLson"<grglsn765@gmail.com> Sent: Thursday, September 22, 2011 4:11am To: "suse"<opensuse@opensuse.org> 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@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
George OLson said the following on 09/23/2011 10:16 AM:
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.
O'Reilley have an excellent series of books in *NIX that includes "Learning the Bash Shell", which covers fundamentals. I suppose the old 1978 Bell Systems Journal is probably the best couple of volumes on basics, but its long out of print. Have they ever been offered on EBay? How much? I wouldn't sell mine, not any of my other UNIX docs and handbooks from that era, unless I was offered a goodly sum. The _are_ collectors items, but you _might_ find them in a technical library somewhere. -- Virtually every major technological advance in the history of the human species-- back to the invention of stone tools and the domestication of fire-- has been ethically ambiguous. --Carl Sagan (The Demon-Haunted World) -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
participants (11)
-
Anton Aylward
-
brian@aljex.com
-
Carlos E. R.
-
Dave Cotton
-
Dave Howorth
-
David Haller
-
George OLson
-
jdd
-
Ken Schneider - openSUSE
-
Philipp Thomas
-
Roger Oberholtzer