My advice:
bash
(and its ilk) are not general purpose programming languages. While it is possible to accomplish some sophisticated scripting in bash
it's not the best way to learn programming in general. It is the most natural way to accomplish systems administration tasks which primarily revolve around executing other programs, handling their data files and directories and marshaling input and output into and from them. If bash
is a hammer, reserve it for problems that really do look like nails. Learning to do anything non-trivial in bash
will be considerably easier if you learn some very small subsets of sed
and awk
(since the string manipulation in bash
is largely inspired by the syntax of similar operations in these "little" languages).
- For general purpose programming under Linux you'll hear many impassioned arguments. The two best contenders are Perl and Python. These are both very high level scripting languages which are general purpose, which expose enough low level functionality to do perform almost any operation that's accessible to any user space process on your system, and with huge collections of pre-written modules and libraries available.
I do recommend that you read an introductory text on C and spend some time running the strace
and ltrace
commands on some simple utility commands like ls
and mkdir
and /bin/echo
etc. (Actually these days I'd suggest ltrace -S
in lieu of strace
but forays into the output from both commands and into the ltrace
output as augmented by the -S
option will be extremely educational).
C is the primary programming language in which the Linux kernel and the GNU libc are written. (Small parts are in assembly). Almost all programs on a Linux (or other UNIX-like) system are linked against the C libraries (libc). The primary Perl and Python interpreters (and most other scripting languages) are also written in C. These programs (the kernel, the common system libraries and the various scripting language interpreters) are all written by C programmers are their design and features are strongly influenced by their underlying implementations. Thus a deeper understanding of any of these eventually entails understanding C. You don't need to know anything about C++ nor Java to understand programming at this level. (Those may each be interesting and necessary in their own right depending on your career patch, but the differences between C and C++ and Java are largely orthogonal to the use of C for most of your system's programs and utilities.
So, if you agree with my premises so far, we've boiled it down to a choice between Perl and Python.
Here's where real flame wars begin.
My advice is to focus on Python (2.x) first. Python has a relatively simple and consistent syntax. You can learn the basics of Python syntax in a few hours and that's the vast majority of the syntax you'll ever encounter. There are only a few features (list comprehensions, generator expressions, decorators) which are wrinkles to the basic syntax. So most of your effort in learning Python will be devoted to learning the extensive standard libraries and trying to find the "best" way to use them (and figuring out which are the specific sets of exceptions that are worth handling to make your programs robust) and, most importantly, in learning the underlying concepts.
I think that Python's extensive libraries and relatively simple syntax does have two distinct disadvantages.
First, as you learn how do to thing in a very high level in Python you might find the thought of having to work at a lower level to be tedious. Where I work Perl is the standard. I prototype my work in Python, where I know I can get it working far more quickly and reliably then in Perl; then I dread having to go through and port it to Perl for my colleagues. (I was reasonably good at Perl years before I ever used Python --- so it's not a matter of simple familiarity).
The other disadvantage is that it's sometimes difficult to find the highest level way to accomplish a given task in Python. For example to fetch a web page you might initially try doing it with low level sockets ... which will work. However, you'd be duplicating quite a bit of code that you can already find including in the urllib
and/or urllib2
modules. The very fact that the standard libraries, as of 2.7.1, includes both of these makes my point. Where possible the maintainers of Python have extended older modules and APIs transparently; however there are dozens of cases where Python retains two or three modules where transparent extension was not possible for some reason. (For another example you could look at the options for parsing command line options: argparse
, optparse
, and getopt
. There's little harm to writing your programs using getopt
(the oldest of these). For very simple utilities with few options and a rigid calling convention (used only by a small group of people, for example) then there's nothing inherently wrong with walking over sys.argv
yourself. However, it's usually worth reading the docs carefully and following the links at the bottoms of older or lower level modules which describe the newer or higher level features available.
My advice is based on my opinion that you want to focus on deeper concepts and not have to spend much of your time and effort on syntactic and language specific issues. Understanding when to use a subprocess, versus a thread, or the multi-processing features that are included with Python has relatively little to do with the language and everything to do with programming proficiency regardless of language. (At the point where you can understand arguments about Twisted's event driven model by comparison to threading and multiprocessing then you'll probably have mastered Python and be ready to program in any language).
The counter argument, for Perl, is simple and practical. There are quite a few more jobs out there which will call, specifically, for skills with Perl. Perl is a powerful language and has extremely extensive libraries. (The core of Perl that's distributed with most Linux system is covers a smaller range of functionality than the standard Python libraries; it's assumed that you'll installed a significant number of additional packages from your distribution or through CPAN --- the Comprehensive Perl Archive Network). (By contrast there are fewer Python modules and packages that I have to fetch separately ... those are available from PyPI --- the Python Package Index).
So, if you learn Perl you'll have a leg up for finding jobs, particularly sysadmin jobs, in the short term. However, Perl's syntax is ... well ... in the words of some of it's own enthusiasts ... "pathologically eclectic!" Perl can be extremely terse and its code is filled with quite a bit of punctuation. Those who love it will argue endlessly that it's "easy" and makes perfect sense --- and will have endless opportunities to do so in forums which are filled with confusion about exactly how a given snippet of code was interpreted. The syntax and the language used in the documentation and by those who support it in public forums are nuanced to the point where you can spend considerable effort to learn them.
Now, please realize that this preceding commentary is subjective and biased. It's possible that you'll try Perl and find it's syntax to be intuitive and pleasant. If so, more power to you. However, I personally find that my grasp of Perl's idiosyncrasies decays very rapidly. The fundamentals I retain but I find it to be a struggle whenever I have to switch back to it for more than a few lines of code.
There are lots of other languages you would study, Java, Lisp and Scheme, TCL, Scala, and so on. However, I'd suggest starting with one that offers the best balance between utility and simplicity.