1

I'm learning to use the terminal on my Ubuntu 14.04 and I'm running command line code in my shell (which I'm told is what is inside the terminal) to install programs. But I can also start my node.js server in my shell and I can then run javascript code in the terminal; it keeps track of values I store in variables and I can create functions and then use them and so on. However it does seem to change mode because I'm no longer in a specific folder of my operating system so maybe I'm no longer in my shell?

So I started looking into shell commands:

What Are "Commands?

According to http://linuxcommand.org/lc3_lts0060.php commands can be one of 4 different kinds:

  1. An executable program like all those files in /usr/bin. Within this category, programs can be compiled binaries such as programs written in C and C++, or programs written in scripting languages such as the shell, Perl, Python, Ruby, etc.

  2. A command built into the shell itself. bash provides a number of commands internally called shell builtins. The cd command, for example, is a shell builtin.

  3. A shell function. These are miniature shell scripts incorporated into the environment.

  4. An alias. Commands that you can define yourselves, built from other commands.

Does this mean that I'm always running the higher level code I have in my files (e.g. x.php, x.js x.css x.html files) with the help of my shell every time I start a program? Or does it only mean that I can use the command line to start a program which then run somewhere else (if somewhere else, then where?)?

How can you grasp the interaction between these different types of code/languages?

For example: can you view it all as code put into a command line; line after line with some languages making calls to other languages which then return the control to the caller and so on, or what kind of mental model is useful for understanding what is going on?

Kriss
  • 113

2 Answers2

4

I've never found anything but bottom-up learning useful to develop a mental model of complex systems.

Learn a bit of assembly language - not a lot, just enough to write a number-adding subroutine. Watch is do its thing by stepping through it in the debugger. Discover that pointers are nothing more than machine addresses, and a string is really a sequence of memory cells terminated by a cell with 0 in it (disclaimer: in some languages).

Once you know that, remembering it when you write in higher-level languages is the best thing you can do to get a coherent image of the entire system. You will immediately understand why some things are slower than others, and why others need more memory.

Once you understand programming languages, have a quick look at the implementation of a command shell. Again, not long, just enough to see that it's a program like other programs, only its input and output are other commands. Watch it parse a command line, and eventually you will 'get' why file names with spaces in them cause so much trouble.

Optionally, look inside a modern system startup daemon and see how it uses shell scripts, programs and system calls to achieve stuff (Try not to be too shocked at how rickety it all seems.)

All this takes time, but I'm firmly of the opinion that you cannot get a halfway useful impression of such a complex system as a modern computer without investing considerable time. It's much more common to go away with a half-wrong, misleading mental model (ask anyone who's ever spent even one day working tech support). It's also unlikely that you will ever understand everything in the stack, but that's okay - nobody understands the entire stack used to compute anything today. The human brain is too slow and too valuable to try such a stunt anymore.

  • Thanks for the answer; it was helpful and I will take your advice. But I had to narrow down the question so that I eventually can get enough points to upvote good answers like yours. :) –  Aug 13 '14 at 10:33
1

You are correct in saying that, when you open a terminal, you are using a shell. The primary job of a shell is to help you run executable programs.

So what is an executable? Type lsand hit return. It should print out the files in the current directory. Now, this looks like the shell is running some sort of inbuilt command called ls, right? Wrong! It's actually creating a new Linux process that runs the executable program /usr/bin/ls.

So why did it write the list of files to the shell? Well, the ls program doesn't know anything about the shell. In fact it has no real idea where it's going to write to. What the programmer did was make the program write the list to something called standard out. The shell then used a Linux trick called a pipe to make the list print to the terminal.

Interestingly, the shell can also make this standard out go to other places. For example, typing ls > /tmp/ls.out won't print to the terminal. It actually is sending the list to a file in the /tmp directory. Even more interestingly, typing ls | less makes the shell start the ls program as well as the less program and pipes the standard out of ls to the standard in of less. Neither of these programs knew anything about the shell nor, in fact, did the shell know about how the programs work: if the program's been coded in the standard way, it'll all just work.

Now, to the node.js case. Again, the shell just started the node.js program. If you don't supply arguments, this program tries to read from standard in just like less. As you didn't pipe anything to it, the shell just hooked up the keyboard so that anything you type gets sent to node. The shell also hooked up standard out to the terminal so that anything node wrote went to the terminal as we saw ls do. The net effect makes it appear that the shell now understands JavaScript but not so. It really just understands executing programs and redirecting in/out (at least in this case). It's node doing the JS.

Alex
  • 126