Free Republic
Browse · Search
General/Chat
Topics · Post Article

Skip to comments.

Linux: Learning the Shell Part 1
linuxcommand.org ^ | Current | William Shotts

Posted on 01/30/2019 7:42:58 AM PST by ShadowAce

Why Bother?

Why do you need to learn the command line anyway? Well, let me tell you a story. A few years ago we had a problem where I used to work. There was a shared drive on one of our file servers that kept getting full. I won't mention that this legacy operating system did not support user quotas; that's another story. But the server kept getting full and it stopped people from working. One of our software engineers spent the better part of a day writing a C++ program that would look through all the user's directories and add up the space they were using and make a listing of the results. Since I was forced to use the legacy OS while I was on the job, I installed a Linux-like command line environment for it. When I heard about the problem, I realized I could do all the work this engineer had done with this single line:

du -s * | sort -nr > $HOME/user_space_report.txt

Graphical user interfaces (GUIs) are helpful for many tasks, but they are not good for all tasks. I have long felt that most computers today are not powered by electricity. They instead seem to be powered by the "pumping" motion of the mouse! Computers were supposed to free us from manual labor, but how many times have you performed some task you felt sure the computer should be able to do but you ended up doing the work yourself by tediously working the mouse? Pointing and clicking, pointing and clicking.

I once heard an author say that when you are a child you use a computer by looking at the pictures. When you grow up, you learn to read and write. Welcome to Computer Literacy 101. Now let's get to work.

What Is "The Shell"?

Simply put, the shell is a program that takes commands from the keyboard and gives them to the operating system to perform. In the old days, it was the only user interface available on a Unix-like system such as Linux. Nowadays, we have graphical user interfaces (GUIs) in addition to command line interfaces (CLIs) such as the shell.

On most Linux systems a program called bash (which stands for Bourne Again SHell, an enhanced version of the original Unix shell program, sh, written by Steve Bourne) acts as the shell program. Besides bash, there are other shell programs that can be installed in a Linux system. These include: ksh, tcsh and zsh.

What's A "Terminal?"

It's a program called a terminal emulator. This is a program that opens a window and lets you interact with the shell. There are a bunch of different terminal emulators you can use. Most Linux distributions supply several, such as: gnome-terminal, konsole, xterm, rxvt, kvt, nxterm, and eterm.

Starting A Terminal

Your window manager probably has a way to launch a terminal from the menu. Look through the list of programs to see if anything looks like a terminal emulator. If you are a KDE user, the terminal program is called "konsole," in Gnome it's called "gnome-terminal." You can start up as many of these as you want and play with them. While there are a number of different terminal emulators, they all do the same thing. They give you access to a shell session. You will probably develop a preference for one, based on the different bells and whistles each one provides.

Testing The Keyboard

OK, let's try some typing. Bring up a terminal window. You should see a shell prompt that contains your user name and the name of the machine followed by a dollar sign. Something like this:

[me@linuxbox me]$

Excellent! Now type some nonsense characters and press the enter key.

[me@linuxbox me]$ kdkjflajfks

If all went well, you should have gotten an error message complaining that it cannot understand you:

[me@linuxbox me]$ kdkjflajfks

bash: kdkjflajfks: command not found

Wonderful! Now press the up-arrow key. Watch how our previous command "kdkjflajfks" returns. Yes, we have command history. Press the down-arrow and we get the blank line again.

Recall the "kdkjflajfks" command using the up-arrow key if needed. Now, try the left and right-arrow keys. You can position the text cursor anywhere in the command line. This allows you to easily correct mistakes.

You're not logged in as root, are you?

If the last character of your shell prompt is # rather than $, you are operating as the superuser. This means that you have administrative privileges. This can be potentially dangerous, since you are able to delete or overwrite any file on the system. Unless you absolutely need administrative privileges, do not operate as the superuser.

Using The Mouse

Even though the shell is a command line interface, the mouse is still handy.

Besides using the mouse to scroll the contents of the terminal window, you can copy text with the mouse. Drag your mouse over some text (for example, "kdkjflajfks" right here on the browser window) while holding down the left button. The text should highlight. Release the left button and move your mouse pointer to the terminal window and press the middle mouse button (alternately, you can press both the left and right buttons at the same time if you are working on a touch pad). The text you highlighted in the browser window should be copied into the command line.

A few words about focus...

When you installed your Linux system and its window manager (most likely Gnome or KDE), it was configured to behave in some ways like that legacy operating system.

In particular, it probably has its focus policy set to "click to focus." This means that in order for a window to gain focus (become active) you have to click in the window. This is contrary to traditional X Window behavior. You should consider setting the focus policy to "focus follows mouse". You may find it strange at first that windows don't raise to the front when they get focus (you have to click on the window to do that), but you will enjoy being able to work on more than one window at once without having the active window obscuring the the other. Try it and give it a fair trial; I think you will like it. You can find this setting in the configuration tools for your window manager.

Navigation

In this lesson, I will introduce your first three commands: pwd (print working directory), cd (change directory), and ls (list files and directories).

If you have not worked with a command line interface before, you will need to pay close attention to this lesson, since the concepts will take some getting used to.

File System Organization

Like that legacy operating system, the files on a Linux system are arranged in what is called a hierarchical directory structure. This means that they are organized in a tree-like pattern of directories (called folders in other systems), which may contain files and other directories. The first directory in the file system is called the root directory. The root directory contains files and subdirectories, which contain more files and subdirectories and so on and so on.

Most graphical environments today include a file manager program to view and manipulate the contents of the file system. Often you will see the file system represented like this:

directory tree

One important difference between the legacy operating system and Unix-like operating systems such as Linux is that Linux does not employ the concept of drive letters. While drive letters split the file system into a series of different trees (one for each drive), Linux always has a single tree. Different storage devices may contain different branches of the tree, but there is always a single tree.

pwd

Since a command line interface cannot provide graphic pictures of the file system structure, it must have a different way of representing it. Think of the file system tree as a maze, and you are standing in it. At any given moment, you are located in a single directory. Inside that directory, you can see its files and the pathway to its parent directory and the pathways to the subdirectories of the directory in which you are standing.

The directory you are standing in is called the working directory. To find the name of the working directory, use the pwd command.

[me@linuxbox me]$ pwd
/home/me

When you first log on to a Linux system, the working directory is set to your home directory. This is where you put your files. On most systems, your home directory will be called /home/your_user_name, but it can be anything according to the whims of the system administrator.

To list the files in the working directory, use the ls command.

[me@linuxbox me]$ ls
Desktop     Xrootenv.0    linuxcmd
GNUstep     bin           nedit.rpm
GUILG00.GZ  hitni123.jpg  nsmail

I will come back to ls in the next lesson. There are a lot of fun things you can do with it, but I have to talk about pathnames and directories a bit first.

cd

To change your working directory (where you are standing in the maze) you use the cd command. To do this, type cd followed by the pathname of the desired working directory. A pathname is the route you take along the branches of the tree to get to the directory you want. Pathnames can be specified in one of two different ways; absolute pathnames or relative pathnames. Let's look with absolute pathnames first.

An absolute pathname begins with the root directory and follows the tree branch by branch until the path to the desired directory or file is completed. For example, there is a directory on your system in which most programs are installed. The pathname of the directory is /usr/bin. This means from the root directory (represented by the leading slash in the pathname) there is a directory called "usr" which contains a directory called "bin".

Let's try this out:

[me@linuxbox me]$ cd /usr/bin
[me@linuxbox bin]$ pwd
/usr/bin
[me@linuxbox bin]$ ls
[                     lwp-request
2to3                  lwp-rget
2to3-2.6              lxterm
a2p                   lz
aalib-config          lzcat
aconnect              lzma
acpi_fakekey          lzmadec
acpi_listen           lzmainfo
add-apt-repository    m17n-db
addpart               magnifier

and many more...

Now we can see that we have changed the current working directory to /usr/bin and that it is full of files. Notice how your prompt has changed? As a convenience, it is usually set up to display the name of the working directory.

Where an absolute pathname starts from the root directory and leads to its destination, a relative pathname starts from the working directory. To do this, it uses a couple of special notations to represent relative positions in the file system tree. These special notations are "." (dot) and ".." (dot dot).

The "." notation refers to the working directory itself and the ".." notation refers to the working directory's parent directory. Here is how it works. Let's change the working directory to /usr/bin again:

[me@linuxbox me]$ cd /usr/bin
[me@linuxbox bin]$ pwd
/usr/bin

O.K., now let's say that we wanted to change the working directory to the parent of /usr/bin which is /usr. We could do that two different ways. First, with an absolute pathname:

[me@linuxbox bin]$ cd /usr
[me@linuxbox usr]$ pwd
/usr

Or, with a relative pathname:

[me@linuxbox bin]$ cd ..
[me@linuxbox usr]$ pwd
/usr

Two different methods with identical results. Which one should you use? The one that requires the least typing!

Likewise, we can change the working directory from /usr to /usr/bin in two different ways. First using an absolute pathname:

[me@linuxbox usr]$ cd /usr/bin
[me@linuxbox bin]$ pwd
/usr/bin

Or, with a relative pathname:

[me@linuxbox usr]$ cd ./bin
[me@linuxbox bin]$ pwd
/usr/bin

Now, there is something important that I must point out here. In almost all cases, you can omit the "./". It is implied. Typing:

[me@linuxbox usr]$ cd bin

would do the same thing. In general, if you do not specify a pathname to something, the working directory will be assumed. There is one important exception to this, but we won't get to that for a while.

A Few Shortcuts

If you type cd followed by nothing, cd will change the working directory to your home directory.

A related shortcut is to type cd ~user_name. In this case, cd will change the working directory to the home directory of the specified user.

Typing cd - changes the working directory to the previous one.

Important facts about file names

  1. File names that begin with a period character are hidden. This only means that ls will not list them unless you say ls -a. When your account was created, several hidden files were placed in your home directory to configure things for your account. Later on we will take a closer look at some of these files to see how you can customize your environment. In addition, some applications will place their configuration and settings files in your home directory as hidden files.

  2. File names in Linux, like Unix, are case sensitive. The file names "File1" and "file1" refer to different files.

  3. Linux has no concept of a "file extension" like legacy operating systems. You may name files any way you like. However, while Linux itself does not care about file extensions, many application programs do.

  4. Though Linux supports long file names which may contain embedded spaces and punctuation characters, limit the punctuation characters to period, dash, and underscore. Most importantly, do not embed spaces in file names. If you want to represent spaces between words in a file name, use underscore characters. You will thank yourself later.

Looking Around

Now that you know how to move from working directory to working directory, we're going to take a tour of your Linux system and, along the way, learn some things about what makes it tick. But before we begin, I have to teach you some tools that will come in handy during our adventure. These are:

ls

The ls command is used to list the contents of a directory. It is probably the most commonly used Linux command. It can be used in a number of different ways. Here are some examples:

Examples of the ls command

Command

Result

ls

List the files in the working directory

ls /bin

List the files in the /bin directory (or any other directory you care to specify)

ls -l

List the files in the working directory in long format

ls -l /etc /bin

List the files in the /bin directory and the /etc directory in long format

ls -la ..

List all files (even ones with names beginning with a period character, which are normally hidden) in the parent of the working directory in long format

These examples also point out an important concept about commands. Most commands operate like this:

    command -options arguments

where command is the name of the command, -options is one or more adjustments to the command's behavior, and arguments is one or more "things" upon which the command operates.

In the case of ls, we see that ls is the name of the command, and that it can have one or more options, such as -a and -l, and it can operate on one or more files or directories.

A Closer Look At Long Format

If you use the -l option with ls, you will get a file listing that contains a wealth of information about the files being listed. Here's an example:



-rw-------   1 bshotts  bshotts       576 Apr 17  1998 weather.txt
drwxr-xr-x   6 bshotts  bshotts      1024 Oct  9  1999 web_page
-rw-rw-r--   1 bshotts  bshotts    276480 Feb 11 20:41 web_site.tar
-rw-------   1 bshotts  bshotts      5743 Dec 16  1998 xmas_file.txt

---------- ------- ------- -------- ------------ ------------- | | | | | | | | | | | File Name | | | | | | | | | +--- Modification Time | | | | | | | +------------- Size (in bytes) | | | | | +----------------------- Group | | | +-------------------------------- Owner | +---------------------------------------------- File Permissions


File Name

The name of the file or directory.

Modification Time

The last time the file was modified. If the last modification occurred more than six months in the past, the date and year are displayed. Otherwise, the time of day is shown.

Size

The size of the file in bytes.

Group

The name of the group that has file permissions in addition to the file's owner.

Owner

The name of the user who owns the file.

File Permissions

A representation of the file's access permissions. The first character is the type of file. A "-" indicates a regular (ordinary) file. A "d" indicates a directory. The second set of three characters represent the read, write, and execution rights of the file's owner. The next three represent the rights of the file's group, and the final three represent the rights granted to everybody else. I'll discuss this in more detail in a later lesson.

less

less is a program that lets you view text files. This is very handy since many of the files used to control and configure Linux are human readable.

What is "text"?

There are many ways to represent information on a computer. All methods involve defining a relationship between the information and some numbers that will be used to represent it. Computers, after all, only understand numbers and all data is converted to numeric representation.

Some of these representation systems are very complex (such as compressed multimedia files), while others are rather simple. One of the earliest and simplest is called ASCII text. ASCII (pronounced "As-Key") is short for American Standard Code for Information Interchange. This is a simple encoding scheme that was first used on Teletype machines to map keyboard characters to numbers.

Text is a simple one-to-one mapping of characters to numbers. It is very compact. Fifty characters of text translates to fifty bytes of data. Throughout a Linux system, many files are stored in text format and there are many Linux tools that work with text files. Even the legacy operating systems recognize the importance of this format. The well-known NOTEPAD.EXE program is an editor for plain ASCII text files.

The less program is invoked by simply typing:

less text_file

This will display the file.

Controlling less

Once started, less will display the text file one page at a time. You may use the Page Up and Page Down keys to move through the text file. To exit less, type "q". Here are some commands that less will accept:

Keyboard commands for the less program

Command

Action

Page Up or b

Scroll back one page

Page Down or space

Scroll forward one page

G

Go to the end of the text file

1G

Go to the beginning of the text file

/characters

Search forward in the text file for an occurrence of the specified characters

n

Repeat the previous search

h

Display a complete list less commands and options

q

Quit

file

As you wander around your Linux system, it is helpful to determine what kind of data a file contains before you try to view it. This is where the file command comes in. file will examine a file and tell you what kind of file it is.

To use the file program, just type:

file name_of_file

The file program can recognize most types of files, such as:

Various kinds of files

File Type

Description

Viewable as text?

ASCII text

The name says it all

yes

Bourne-Again shell script text

A bash script

yes

ELF 32-bit LSB core file

A core dump file (a program will create this when it crashes)

no

ELF 32-bit LSB executable

An executable binary program

no

ELF 32-bit LSB shared object

A shared library

no

GNU tar archive

A tape archive file. A common way of storing groups of files.

no, use tar tvf to view listing.

gzip compressed data

An archive compressed with gzip

no

HTML document text

A web page

yes

JPEG image data

A compressed JPEG image

no

PostScript document text

A PostScript file

yes

RPM

A Red Hat Package Manager archive

no, use rpm -q to examine contents.

Zip archive data

An archive compressed with zip

no

While it may seem that most files cannot be viewed as text, you will be surprised how many can. This is especially true of the important configuration files. You will also notice during our adventure that many features of the operating system are controlled by shell scripts. In Linux, there are no secrets!


TOPICS: Computers/Internet
KEYWORDS: linux
Navigation: use the links below to view more comments.
first previous 1-2021-4041-44 next last
To: ShadowAce

Nothing posted is better than a GUI. You might as well claim the steering wheel in cars is a dumb idea.

The claim that clicking a mouse is less useful or is terrible compared to clicking the keyboard is just plain retarded.


21 posted on 01/30/2019 10:34:38 AM PST by CodeToad ( Hating on Trump is hating on me and America!.)
[ Post Reply | Private Reply | To 1 | View Replies]

To: CodeToad

You can’t easily program a GUI nor can you program it to accomplish a complex task, unattended, 24 hours a day, seven days a week.

There are many tasks that one simply cannot do with a GUI.

One skill set is that of a user the other is a “Power User”.

It all depends on what you want to accomplish and with how much effort.


22 posted on 01/30/2019 10:39:26 AM PST by lurked_for_a_decade (Imagination is more important than knowledge! ( e_uid == 0 ) != ( e_uid = 0 ). I Read kernel code.)
[ Post Reply | Private Reply | To 21 | View Replies]

To: adorno
"I was a coder for many years, and developer/systems-analyst/programmer-analyst/project-manager/independent-IT-consultant for most of my life."

Man, the white privilege is just dripping off of you. Off with your head!

23 posted on 01/30/2019 11:11:29 AM PST by Garth Tater (What's mine is mine.)
[ Post Reply | Private Reply | To 8 | View Replies]

To: CodeToad
The claim that clicking a mouse is less useful or is terrible compared to clicking the keyboard is just plain retarded.

How long would it take you, using a GUI, to update and reboot 500 servers?

Using the CLI, I can do it in less than 30 minutes.

Which method is retarded?

24 posted on 01/30/2019 11:14:26 AM PST by ShadowAce (Linux - The Ultimate Windows Service Pack)
[ Post Reply | Private Reply | To 21 | View Replies]

To: Garth Tater
Man, the white privilege is just dripping off of you. Off with your head!

Except that, I'm not considered white. I'm considered part of an oppressed minority, specifically Hispanic, more specifically Puerto Rican (though I haven't even been to P.R. in about 35 years).
25 posted on 01/30/2019 11:22:57 AM PST by adorno
[ Post Reply | Private Reply | To 23 | View Replies]

To: lurked_for_a_decade
Political battles are know being fought on the internet. Knowledge is our friend!?

FR is on the internet, just so you 'no' (or is it 'now'?). Knowledge is our friend.
26 posted on 01/30/2019 11:25:27 AM PST by adorno
[ Post Reply | Private Reply | To 20 | View Replies]

To: adorno
Oh, I see. One of those white-hispanics then. You are still on the list hombre.

27 posted on 01/30/2019 11:33:37 AM PST by Garth Tater (What's mine is mine.)
[ Post Reply | Private Reply | To 25 | View Replies]

To: Garth Tater
Oh, I see. One of those white-hispanics then.

Yeah! Now you got it!

I am a closet white person.

But, don't tell anybody. I don't want to be accused of being 'whitey' while 'brown'.
28 posted on 01/30/2019 11:43:05 AM PST by adorno
[ Post Reply | Private Reply | To 27 | View Replies]

To: lurked_for_a_decade

Sure there is. The exact same code a command line uses so can a GUI. There is no reason to separate the two. Ya just gotta be a good software engineer and not be lazy.


29 posted on 01/30/2019 11:47:32 AM PST by CodeToad ( Hating on Trump is hating on me and America!.)
[ Post Reply | Private Reply | To 22 | View Replies]

To: ShadowAce

I can do it in seconds using a GUI tool.
I can also do it seconds using a command line.

Smart engineers know how to design both.


30 posted on 01/30/2019 11:48:51 AM PST by CodeToad ( Hating on Trump is hating on me and America!.)
[ Post Reply | Private Reply | To 24 | View Replies]

To: Garth Tater
"Man, the white privilege is just dripping off of you. Off with your head!"

Such an eloquent OP about the Linux command shell, and 25 replies to boot, and this one line contains the only reference to the single most important shell command:


man





Oh, and if command line weren't important, M$ wouldn't have taken the time (and spent the money) to include first a command line interpreter (AKA "Command Line"), then a command-line shell (AKA "PowerShell"), finally throwing in the towel, admitting they were outmatched and baking an Ubuntu-based BaSH shell into Windows 10.

31 posted on 01/30/2019 12:12:05 PM PST by Paal Gulli
[ Post Reply | Private Reply | To 23 | View Replies]

To: Paal Gulli
Definitely one of the top ten, but man is no where near as useful as the all-time greatest command: su

Sure, I can trash the world running as root, but who has time to worry about little things like user permissions?
32 posted on 01/30/2019 12:28:31 PM PST by Garth Tater (What's mine is mine.)
[ Post Reply | Private Reply | To 31 | View Replies]

To: Garth Tater

Or little things like trashing the world!


33 posted on 01/30/2019 1:28:08 PM PST by lurked_for_a_decade (Imagination is more important than knowledge! ( e_uid == 0 ) != ( e_uid = 0 ). I Read kernel code.)
[ Post Reply | Private Reply | To 32 | View Replies]

To: Garth Tater

During a job interview we asked a sysadmin candidate, “Off the top of your head, what is the UNIX command you have used most?” Without hesitation she said, “Colon W Q” | :wq

The silence in the room was finally broken after a minute or so by the question”Remind us again of your primary duties in your last job.


34 posted on 01/30/2019 2:02:09 PM PST by lurked_for_a_decade (Imagination is more important than knowledge! ( e_uid == 0 ) != ( e_uid = 0 ). I Read kernel code.)
[ Post Reply | Private Reply | To 32 | View Replies]

To: ShadowAce

I like it that he is coy about the identity of the legacy operating system that uses drive letters in organizing the filesystem.


35 posted on 01/30/2019 3:29:11 PM PST by Mmmike
[ Post Reply | Private Reply | To 1 | View Replies]

To: ShadowAce

Interesting stuff.

I had a fold out list of Linux commands a while back, but not sure where it is now, never used it much. Probably still in an old laptop case. Plenty can be done with command line, but I mostly used the GUI with Linux, I wanted to see if it was “ready for prime time” if I used it just like the average idiot who can barely turn a computer on. So that’s the way I used it, exactly the opposite of the way I approached Windows.

I built and repaired Windows computers for a living for around 15 years, used the DOS OS plenty, so I’m fairly familiar with the difference between GUI and command line, just never used it with Linux, I wanted to dive in and use it just like anyone would a Windows machine.

At that time, running Mandrake 9, it wasn’t quite ready yet, but close. Everything worked well, but it took a bit of a learning curve. I’ve also used Knoppix, Ubuntu, Damn Small Linux, Feather, Puppy, and now running Slacko 6.3.2 (puppy version) on another laptop, a live CD version that works well, I’ve browsed FR and posted a few times with it.

My first full install, Mandrake 8, was pretty hairy, but after that it wasn’t bad at all. The few times I’ve had a reason to use the command line it worked quite well, like installing a nVidia driver on the Mandrake 9 machine. Some of the commands are similar to DOS, if I remember correctly most are different. Both work very close to the same though, if you know what command you need.

I originally learned by working on older pure DOS machines, the old 4.77 mhz XT and 286 machines, a 10 MB hard drive was the max you could get, in some cases 5 1/4” floppy only. The average calculator today puts it to shame...but it was fun, still hard to beat some of the really old DOS games. I think I still actually have DOS 6 and Windows 3.1 on an old 266mhz laptop and a few games on it. Also still have Linux CDs that will run quite well on that range computer, many will run on older hardware. Mandrake 9 would run great on a machine that would just barely run XP at all, both released about the same time. That was my favorite thing about Linux, I could still use a P-III 500 that would be so sluggish running XP I wouldn’t even install it at all.

I’ll have to bookmark this one for future reference...


36 posted on 01/30/2019 6:03:55 PM PST by Paleo Pete (I'm not lost, I know exactly where I am. I'm right here...)
[ Post Reply | Private Reply | To 1 | View Replies]

To: CodeToad

I telnet to unix severs all over the USA and use command line every day. How would I do that with a GUI?


37 posted on 01/30/2019 6:13:35 PM PST by central_va (I won't be reconstructed and I do not give a damn)
[ Post Reply | Private Reply | To 21 | View Replies]

To: lurked_for_a_decade

Vi forever.


38 posted on 01/30/2019 6:15:51 PM PST by central_va (I won't be reconstructed and I do not give a damn)
[ Post Reply | Private Reply | To 34 | View Replies]

To: central_va

Easy. The same IO performed by a command line can be performed by a GUI. Under the covers there is no difference. There is nothing magical about a command line.


39 posted on 01/30/2019 7:59:08 PM PST by CodeToad ( Hating on Trump is hating on me and America!.)
[ Post Reply | Private Reply | To 37 | View Replies]

To: CodeToad

So how do I use a gui logged into a server 500 miles form me?


40 posted on 01/31/2019 4:48:46 AM PST by central_va (I won't be reconstructed and I do not give a damn)
[ Post Reply | Private Reply | To 39 | View Replies]


Navigation: use the links below to view more comments.
first previous 1-2021-4041-44 next last

Disclaimer: Opinions posted on Free Republic are those of the individual posters and do not necessarily represent the opinion of Free Republic or its management. All materials posted herein are protected by copyright law and the exemption for fair use of copyrighted works.

Free Republic
Browse · Search
General/Chat
Topics · Post Article

FreeRepublic, LLC, PO BOX 9771, FRESNO, CA 93794
FreeRepublic.com is powered by software copyright 2000-2008 John Robinson