17

(I'm not sure if it's a appropriate question here)

Shell scripts, like those written in bash, can do many things. They can call Unix programs, pipe their output, redirect I/O from/to files, control flow, check whether a file exists, etc.

But a modern programming language, e.g, python and ruby, can also do these things. And, they are (I think) more readable and maintainable.

bash enjoys wide spread adoption. But many distributions have installed python interpreter, too.

So what's the advantage of shell a script? If I could write python, ruby or perl, is it worth to learn bash?

3

8 Answers 8

32

Shells have specialized features for working with files and getting data from one program into another (assuming that data is text). For those tasks, shell scripts can be less cumbersome than a scripting language like Python.

Shell scripting also has the advantage that the commands you use are basically the same commands you'd use from the command line -- so if you can do something in the shell, you're more than halfway to scripting the same operation.

Here for example is a bash script that moves all the PNG files from the current directory to a specified directory.

#!/usr/bin/sh
mv *.png $1

Here's a Python version.

#!/usr/bin/python
import sys, shutil, glob
for filename in glob.iglob("./*.png"):
    shutil.move(filename, sys.argv[1])

You'll notice:

  • The bash script is a third as long as the Python if you count lines (excluding the shebang line) -- even less by character count. In fact, you probably wouldn't even write a script for it, you'd just create an alias.
  • The Python script requires three libraries to be imported, while everything you need for this task is natively available in bash.
  • The Python script requires an explicit loop to move the files, whereas that is part of the semantics of the mv command in bash.
  • The bash script can run faster -- you'll probably invoke it from bash, and you can use source to run it in the same instance of the shell.
  • glob.iglob("./*.png") is quite a mouthful just to say *.png

If you wanted to write a basic pipe operation in Python, you would be astounded at the verbosity. (Of course, some things, like piping through grep, can be replaced by Python code rather than using an external program, so you often don't need to pipe quite as much.)

As a counterexample, I once had to write a routine that checked to see how long each of the filenames were in a particular directory. If they were longer than supported by a particular OS, they had to be shortened. This could result in duplicate filenames, which I needed to rectify, and since they would be linked from a Web page, the shortened names needed to be stable, i.e., they should be generated in such way that the same long filename would always result in the same shortened filename. I did this by generating a hex md5 of the long filename and appending the first four characters of that to the shortened name (names could still collide, but it was very unilkely, so I just checked for that condition and bailed if it should happen). It also had to record the rename operation so a batch search-and-replace could later be done on the files to fix the links between them (I wrote out a sed command file and passed that to sed for each file).

I did this in bash because it was part of our build system which was already written in bash. It was exactly as hard to get right as you are probably thinking. It would have taken a lot less time to write in Python and probably would have been clearer, too.

In short: different languages are designed for different kinds of tasks; choose the language available to you that is best suited to the task at hand.

1
  • You cant do the same in perl #/usr/bin/perl mv *.png $1 (comments do not retain formatting) but with perl you can also use higher level language features.
    – Poma
    Jul 23, 2012 at 7:48
19

The existing answers are also valid, but there's one reason that no one has mentioned yet: because it WILL be there.

Any given *nix install is done with some set of optional packages which may or may not be loaded, and not all systems will have Python or Perl or Ruby. But if the system is expected to have any interactive capability at all, it will have a shell. This means that shell scripts will work on systems from servers to programmer's desktops to secretarial thin-client desktops to embedded devices, on any system that supports a writable file system and a bash command line.

For someone who only ever works in a consistent server environment, this is something that can be taken for granted, and isn't so important. For someone working in a more varied environment, this should not be overlooked.

0
12

A significant portion of your question is answered here:

Why are scripting languages (e.g. Perl, Python, Ruby) not suitable as shell languages?

Here's an excerpt from my answer to that question:

There are a couple of differences that I can think of; just thoughtstreaming here, in no particular order:

  1. Python & Co. are designed to be good at scripting. Bash & Co. are designed to be only good at scripting, with absolutely no compromise. IOW: Python is designed to be good both at scripting and non-scripting, Bash cares only about scripting.

  2. Bash & Co. are untyped, Python & Co. are strongly typed, which means that the number 123, the string 123 and the file 123 are quite different. They are, however, not statically typed, which means they need to have different literals for those, in order to keep them apart. Example:

    • Ruby: 123 (number), Bash: 123
    • Ruby: '123' (string), Bash: 123
    • Ruby: /123/ (regexp), Bash: 123
    • Ruby: File.open('123') (file), Bash: 123
    • Ruby: IO.open('123') (file descriptor), Bash: 123
    • Ruby: URI.parse('123') (URI), Bash: 123
    • Ruby: `123` (command), Bash: 123
  3. Python & Co. are designed to scale up to 10000, 100000, maybe even 1000000 line programs, Bash & Co. are designed to scale down to 10 character programs.

  4. In Bash & Co., files, directories, file descriptors, processes are all first-class objects, in Python, only Python objects are first-class, if you want to manipulate files, directories etc., you have to wrap them in a Python object first.

  5. Shell programming is basically dataflow programming. Nobody realizes that, not even the people who write shells, but it turns out that shells are quite good at that, and general-purpose languages not so much. In the general-purpose programming world, dataflow seems to be mostly viewed as a concurrency model, not so much as a programming paradigm.

I have the feeling that trying to address these points by bolting features or DSLs onto a general-purpose programming language doesn't work. At least, I have yet to see a convincing implementation of it. There is RuSH (Ruby shell), which tries to implement a shell in Ruby, there is rush, which is an internal DSL for shell programming in Ruby, there is Hotwire, which is a Python shell, but IMO none of those come even close to competing with Bash, Zsh, fish and friends.

3
2

I would say a shell script has the advantage in situations where you just want to whip up a super-simple automated task. For example, if you wanted to write a script that backs up a directory from one server to another every day at 5:00, it would be overkill to use a heavy duty programming language.

On the other hand, if your programming task has more of a need for control structures (if/then/else), iterative structures(looping), database & file I/O, etc, then it is probably better suited for a more capable programming language than a shell script.

I think a good rule of thumb is:

automatingSimpleTask ? shellScript() : programmingLanguage();
2
  • 2
    Shouldn't it be shellScript() if automatingSimpleTask else programmingLanguage() lol.
    – gahooa
    Mar 23, 2012 at 17:33
  • 1
    @gahooa haha shows which side of the fence I'm on!
    – CFL_Jeff
    Mar 23, 2012 at 17:42
2

While you can launch programs from a python/ruby/whatever program, it's different in the shell. You may need to use an API to launch something - fork() for example. In a shell script, programs behave more like functions in a conventional programming language and can be executed, piped, etc with minimal effort. The flow of data is very clear using pipes too.

0

If you are totally free to choose the programming language you use for certain tasks, you could probably almost completely avoid learning bash and do every script programming task with Perl, Python or Ruby. This may sometimes lead to a more verbose solution, especially in the case when you just need a script calling a sequence of other Unix tools, but in more complex cases you are right, those modern script languages give you more possiblites to write better maintainable code (they give you also more possibilites to write obfuscated code, but thats your choice).

On the other hand, often we are not free to choose the language we like most, because we have to work with legacy code or code written by one who knew bash but did not know one of the scripting languages you named.

0

Shell scripting is an interpreted programming language. Here are a few reasons why I chose to write scripts in bash instead of perl or python or some other scripting language:

Works everywhere: More complex interpreters may not always be available, such as during system startup or on embedded systems. Bash is available even in busybox.

Works on the command line: If you're well-versed in shell-scripting, you can use those skills to do complex things in ad-hoc scripts right on the command line. I use this skill daily as a sysadmin.

Easier to write programs that call other programs: If what you're trying to do is chain several existing programs together in interesting ways, it can be simpler to do in a shell script than with a higher-level language.

If the program is 30 lines or less, I'll usually write it using shell scripting. If there is any complex manipulation or complex or analysis to deal with, I'll do it using python or perl.

-1

You should take a look at coffeescript. Their words:

Underneath all those awkward braces and semicolons, JavaScript has always had a gorgeous object model at its heart. CoffeeScript is an attempt to expose the good parts of JavaScript in a simple way.

The golden rule of CoffeeScript is: "It's just JavaScript".

Well... here comes the super-beginner answer.

As an auto-learning beginner for the last 6 months, and tasting a little bit of C, C++, Javascript, and more Bashscript in the last days... I can tell you:

Shell scripts, like those written in bash, can do many things. They can call Unix programs, pipe their output, redirect I/O from/to files, control flow, check whether a file exists, etc.

and isn't this simple fantastic!? loops and variables? wow!

python and ruby, can also do these things. And, they are (I think) more readable and maintainable.

Please, tell me where you see this? I wrote bashscript in gedit even in geany and I can format, (tabs?) and I read my code in the speed of light using bashscript in comparision on other languages.

Does this languages have other tools to keep order? I know object-oriented save a LOT of code, but... people say bashscript is OO too! WOW 2 ! That's my point here. Going to:

the advantage of shell a script

is inside this question: How to do what this bashdamnthing can do in perl or phyton or ruby? It 's easy?

(bashdamnthing = xdotool)

1
  • WTF is going on here? It's a like a Doge answer..
    – naught101
    Jul 26, 2016 at 1:33

Not the answer you're looking for? Browse other questions tagged or ask your own question.