BASH – Shellshock


The PATH to /home/timmy/grannys_house (Revisited)

Back in the old days, when Timmy wanted to visit granny’s house, all he had to do was have Lassie lead him there. In today’s more complicated computer world, it takes a bit more understanding.

We’re going to learn a bit about a very important subject in Linux. It’s called PATH. The path to a file or whatever on your Linux operating system is something that you need to understand when manipulating files from the command line. Another term we’ll look at briefly is the working directory.

When Timmy, as a regular user, opens his terminal from his GUI or from the post login command line (Run Level 3 – multi-user, no X running), his working directory is in /home/timmy. Whichever directory you are in at the time is known as the working directory. Timmy may navigate to another directory using the cd command. Let’s say he navigates to /usr/bin. At that time, his working directory becomes /usr/bin. See how this works?

Think of the Linux file system as a multi-room house. If you’re in bedroom4 right now, your working directory would be /house/bedroom4. If you walked out of that room and down the hall to bathroom02, then your working directory becomes /house/bathroom02. At that time, you may then use the command micturate. Heh! A little bathroom humor there.

OK, so now we know all about the working directory, right? Moving on…

Let’s say that Timmy wants to copy a .jpg that is in /usr/share/wallpaper over to the /home/timmy/grannys_house directory. He would open his terminal, which would then be sitting there with that blinking cursor waiting for Timmy’s next command:

timmy@lassies_machine~:$ |

Timmy’s working directory at this point is /home/timmy, as designated by the command line shorthand character ~ . If Timmy wants to copy the .jpg without actually going to the directory that it’s in to copy it, he must provide the proper path in his command.

timmy@lassies_machine~:$ cp /usr/share/wallpaper/cabin.jpg /home/timmy/grannys_house

The above command, using absolute path names, directs the shell (command line interpreter) to copy the cabin.jpg image from the /usr/share/wallpaper directory to the /home/timmy/grannys_house directory. If Timmy wanted to just make a duplicate of a file in his /home/timmy directory, then he could leave off the / character when showing the command line the proper path. This can be done because he’s already in the /home/timmy directory. It is his working directory. He can now use a relative path to direct the shell to make the copy.

timmy@lassies_machine~:$ cp cabin.jpg cabin.jpg_backup

In the above example, notice that there is no / being used. Timmy is simply making a backup copy of cabin.jpg. Both files are relative to his working directory, so the shell understands that Timmy just wants to make this duplicate right there in that same directory.

It’s really not rocket science, to use that worn out old cliché. The command line can be pretty simple once you get the hang of it folks. You know what I always say… Don’t fear the command line. I hope you’ve learned something here today. Remember to click the links within the article. You’ll find some more useful information and a few definitions for you there.

Later…

~Eric

Further reading:

Unix Commands @ Wikipedia

LinuxTutorial.info

Linfo.org

Paul Sheer’s Rute Users Tutorial and Exposition

Image credits: Timmy (Jon Provost) and Lassie image owned and copyright by Classic Media

Note: This article originally appeared on my old Nocturnal Slacker/Lockergnome Blog (now defunct).


A Few More Shell Basics

In our last lesson here, I scratched the surface of the basics needed to start scripting in BASH. Today, we’ll learn a few more things.

Here are some fundamentals that we need to cover real quick. It’s nothing too complicated.

chmod – You’ve seen this command in action before, I’m sure. It’s important when it comes to writing shell scripts because it allows the script to become executable. This is, of course, a necessity if we want the script to actually run and do something.

#! – These two symbols used in this particular order at the beginning of a script specifies which shell we want to use to run this script. We will primarily be talking about BASH here in these lessons, but let’s say we wanted to write a script that used the tcsh shell instead. The first line of the script would be:

#!/bin/tcsh

The operating system would check that first line initially to determine what shell we intended when we wrote the script. It would then call up that shell and run the script. You’ll see that a lot when programming in BASH. Now you know what it does.

# – This symbol signifies a comment. You’ve probably seen this many times already in configuration files like GRUB’s menu.lst or your distribution’s repository configuration file, maybe. It’s not at all uncommon to find this symbol used in many different programming languages to alert the OS (and the user) that the data on the same line following the # is an informational comment of some sort. Comments are GOOD things when programming. Make lots of comments. They will help you and maybe others who use your program or script down the road. Here’s an example of a commented snippet of script:

#!/bin/bash
# ZIP-100 mknod script – 07222006 – Bruno
mknod /dev/hdb4 b 3 64
#End script

You can see the initial #! telling the OS what shell to use. In the next line, you can see the # symbol followed by some informational data. This was an actual script that I used to need to run at boot to get my ZIP-100 drive to be recognized by the OS. Newer kernels later on solved the issue by using udev, but that’s a whole ‘nother subject. I just wanted you to see what a comment looks like in a BASH script.

; and <newline> – These two devices, when used in the shell, denote a transition from one command to another. For example, if I had three commands called c1, c2, and c3, I could run them on the same line using the ; (semi-colon) to separate them. Or I could just put each of them on a new line. Here’s what I mean…

$ c1;c2;c3 <ENTER to execute>

$ c1 <ENTER>
$ c2 <ENTER>
$ c3 <ENTER>

Pretty simple so far, huh? OK. Let’s continue…

\ – The backward slash is used to continue a command from one line to the next. Like this:

$ echo “She sells seashells \

> by the seashore.” <ENTER>

She sells seashells by the seashore.

Without the \, the line would have been broken when displayed by the echo command’s output. Like this:

$ echo “She sells seashells

> by the seashore.” <ENTER>

Sea sells seashells

by the seashore.

See the difference? Cool! OK, then… just a few more for today. We don’t want to get a headache by stuffing too much in there at one time.

| and & – These two are very cool, and you’ll see them a lot. The first one is called a “pipe”, and that’s just what it does. It pipes output of one command into the input of another. The ampersand (&) symbol tells the shell to run a command in the background. I should briefly diverge here for a moment and mention foreground and background operations so you’ll understand what they are.

A quick sidebar lesson…

You can run a command in the foreground (actively running before your eyes) or in the background (hidden from view but still going). The way to do this is to use the bg and fg command modifiers in the command line. Let’s look a a couple simple examples. Let’s say Mary wants to run some big admin job in the background while she does other stuff in the foreground. It’s pretty easy to do. First she starts big_job01 from the command line.

mary@workplace:~$ big_job01

bla-bla-bla-big_job_running_now-bla-bla-bla

With big_job01 running actively in the foreground, Mary doesn’t have a cursor blinking at the command line. She cant do any other work because she has to watch big_job01 outputting. To change this, Mary will “background” big_job01 to bring back her command line cursor so she can do other things.

CTRL+Z

What this combination of keystrokes will do for Mary is it will stop the process big_job01, giving this notification:

1]+  Stopped                 big_job01

Now Mary will get her cursor back and she can send the big_job01 to the background and get it running again.

mary@workplace:~$ bg 1

She can check to see that it’s in the background and running by listing the jobs.

mary@workplace:~$ jobs -l

1]+  4107 Running                 big_job01 &

Note the following & in the above line. That’s telling Mary that big_job01 is running in the background. Cool, huh? Now Mary can go on about her other chores in the foreground as she normally would. When big_job01 finishes, the command line will give Mary a notification like this:

1]+ Done                                         big_job01

OK, there you have it… a bit about backgrounding and foregrounding operations within the shell. Now let’s go back to what we were talking about before.

( and ) – The parenthesis are used in shell scripting to group commands. The shell will actually create a copy of itself, called a sub-shell, for each group. Groups are seen by the shell as jobs and process IDs are created for each group. Sub-shells have their own environment; meaning they can have their own variables with values different from other sub-shells or the main shell. A bit confusing, huh? Well, let’s see a quick example and then wrap up this lesson so we can all go watch C.S.I. on TV.

$ (c1 ; c2) & c3 &

In the above example, grouped command c1 and c2 would execute sequentially in the background while executing command c3 in the background. Remember that we can background commands by using the ampersand (&) symbol and separate commands by using the semi-colon (;). The prompt would return immediately after hitting ENTER on the line above because both jobs would be running in background. The shell would run the grouped commands  c1 and  c2 as one job and c3 as another job. Clear as chocolate pudding, huh? Don’t worry. It’ll all come together… I hope.

Until next time….

~Eric


Some BASH Basics

Before we get ahead of ourselves, it would probably be a good idea to go over some BASH basics.

Let’s start at the beginning, OK? The Bourne Shell was born at AT&T’s Bell Laboratories a while back. It was birthed by Steve Bourne, hence the name. The Bourne Again Shell (bash) is a direct descendent of the Bourne Shell (sh). It’s very similar to the critter that Mr. Bourne brought to life back at Bell Labs.

There are different types of shells for different purposes. You can have a login shell, which is interactive; a non-login shell, which is also interactive; and a non-interactive shell, like the one used to execute a shell script.

The characteristics of these shells are usually determined by a file in the user’s /home directory called .bashrc. It’s sort of like a configuration file in that items place within it will be faithfully followed by the shell when it is initialized. We’ve seen this already when we were pimping our BASH prompt in a previous article here. I’m over-simplifying, of course. There are other files, be they root or user oriented, that also affect BASH’s behavior. However, we don’t need to go into that at the moment. For now we just want to get a bit more familiar with BASH.

Symbols are an important part of BASH scripting. Some commonly used ones are (, ), [, ], and $. You can see them in action in this snippet of a script:

}

initialize_Suits ()
{
Suits[0]=C #Clubs
Suits[1]=D #Diamonds
Suits[2]=H #Hearts
Suits[3]=S #Spades
}

initialize_Cards ()
{
Cards=(2 3 4 5 6 7 8 9 10 J Q K A)
# Alternate method of initializing an array.
}

Standard Input, Standard Output, Standard Error You may run across these terms while experimenting with and learning BASH. The first is usually provided by your keyboard; typing, in other words. The second is just the printed reply that BASH gives you in the command line. The third is the standard error notice that BASH will give you when it can’t find something or follow a command you’ve entered. Here’s an example of an error:

$ cat jimy_grades.txt

cat: jimy_grades.txt: No such file or directory

You list the contents of your working directory and find that you mis-spelled that file. It’s actually jimmy_grades.txt. This is why the cat command could not find it and BASH provided that standard error output for you. You can also redirect inputs and outputs in BASH using the | and < > symbols. We’ll see redirection in action a bit more later on when we write a few simple scripts to do stuff.

What is a shell script? Well, it’s a file that tells the shell (BASH, in our case) to do something. How does it do this? We “code” or write step-by-step commands and subcommands within the script, using variables and flow control, to make the shell follow these logical steps to achieve our goal.

You can write scripts to do just about anything on your systems. For example, you can write scripts that automate backup or updating chores, etc. You can write scripts to randomly change your desktop wallpaper. You can write scripts that do mulitple chores for you; some become quite multitasking in nature, with more than just a single result. Scripts can be very useful tools.

Writing code, or scripting, is like learning any other human language. It takes time and effort to learn… and lots of practice. You have to practice what you learn or you’ll lose it the same way folks lose their second languages if they don’t speak or read/write them regularly.

We made a simple script in yesterday’s lesson. We showed how Mary was able to write a small script at her workplace that simplified a chore that she had to perform often during the day. We’ll move ahead in the coming days to more complicated scripting, but nothing too complicated. The goal here is just to familiarize you with shell scripting, not to make you and expert. Only you can make you an expert.

More soon…

~Eric

Note: As always, please remember to click on the embedded links within my articles for definitions to unusual words, historical background, or links to supplemental informative sites, etc.


Beginning Shell Scripting

OK, let’s continue on with our lessons about the Linux Shell and the command line.

Today, we’re going to learn how to write a script that you can run from the command line that will actually do stuff. It’s a very simple script, so don’t expect anything spectacular. I was wondering what I could use as an example script for this lesson when I remembered a question someone at LinuxQuestions.org asked the other day about how to tell which users are currently logged into a Linux system. Let’s make a little script to give us that information.

Let’s say that Mary wants to see who is logged in on the Linux system that she maintains for her company. She could easily do this with one simple command from the command line:

mary@workplace:~$ who

bill           pts/4       April 10 09:12

james       pts/5       April 10 09:30

marjory    pts/11     April 10 10:02

ken           pts/16     April 10 10:31

That was pretty easy, right? What if Mary wanted to check this periodically during the day? Well, she could write a small shell script with the proper permissions that she could execute any time she wanted from the command line or the terminal within her graphical user interface. Let’s find out how she might do that.

Mary would first open the vim editor with the file name that she plans to use for this script:

mary@workplace:~$ vim onsys

Vim would faithfully carry out the command and open up ready to edit file onsys. At which point, Mary would enter these lines to create her script:

# custom who script – mary – 10 Apr 11

date

echo “Users currently logged into the system:”

who

# end of script

Here’s what Mary actually did… she made a comment in the first line that begins with the character #, so that the shell knows to ignore that line. In the next line, she sets the command “date” so the script will output the date along with whatever else she requests it to do. In line 4, she uses the built-in echo command to tell the shell to display whatever is being asked for following the echo command. In this case, Mary wants the script to display Users currently logged into the system: when she runs it. The next command that Mary enters into this little script is the built-in who command. And lastly, is her notation that the script has ended.

Now, to make this script work, Mary needs to make it executable. In other words, she has to change the file’s permissions to allow herself (and other, if she wants) to execute (make it run) the script onsys. She will do that this way:

mary@workplace:~$ chmod +x onsys

If she now listed the permissions for this file, they would look like this:

mary@workplace:~$ ls -l onsys

-rwxr-xr-x 1 mary users 94 Apr 10 15:21 onsys

What this means is that everyone on the system can read and execute this script, but only mary can write to (change) it.

OK, so Mary wants to test her script now, so she just types in the script name at the command line (assuming the script is in her working directory):

mary@workplace:~$ onsys

Sun Apr 10 15:48:09 EDT 2011

Users currently logged into the system:

bill           pts/4       April 10 09:12

james       pts/5       April 10 09:30

marjory    pts/11     April 10 10:02

ken           pts/16     April 10 10:31

And so, there you have it. Mary wrote a simple script using shell built-in commands to perform a function that she does repetitively every day. That’s what scripts do. They perform tasks for us at our bidding. Of course, scripts can get much more complicated; so complicated in fact as to be considered applications in their own right. A script is just a series of encoded commands and variables designed to do something, which is basically what an application is also.

Start yourself a directory in your /home directory where you can create and play around with scripting and scripts. It can really be fun. You can “automate” a lot of every day stuff that you do on your computer using custom-made scripts. Yes, you can do it. It ain’t rocket science. It is similar to the technology used to program rockets, though.

Have FUN!

~Eric


Pimp My Bash Prompt

In the next couple lessons here at Nocturnal Slacker v1.0 we’ll be discussing the Bourne Again Shell (BASH) in a bit more detail.

With that in mind, though, how ’bout we play around with a neat trick that will customize your BASH prompt whenever you go to the command line? Sound like fun? OK, here we go…

There’s a file in your /home/<your_username> directory called .bashrc. You’ll need to use the -a (all) option when listing (ls) that directory because the preceding . means it’s a hidden file. So, let’s see how joe would do this…

joe@mysystem:~$ ls -a .bashrc

.bashrc

There we go. So Joe now knows that he does have a .bashrc file in his /home directory. Now, let’s say that Joe wants a cool BASH prompt like mine:

vtel57_Slackware~:$

… that shows his username, his operating system, and his working directory. To do this, Joe is going to have to add a little data to his .bashrc file. He’ll edit the file using the VIM command line editor. Remember that from a previous lesson? Here goes Joe…

joe@mysystem:~$ vim .bashrc

And poof! Up comes VIM with the .bashrc file ready to be edited. It’s almost like magic, huh?

# /home/joe/.bashrc

# custom prompt
PS1=”\u | archlinux\w:$ “

Joe is going to edit the .bashrc file to add the little bit in purple that you see above. What that will do is tell BASH to start up the command line with a prompt the shows Joe’s usersname (u), his distribution (ArchLinux) separated by the | (pipe) character; and his working directory (\w). After saving the file, this is what Joe’s command line prompt will look like once he starts his next BASH session:

joe | archlinux~:$

Pretty neato, huh? Remember the ~ denotes the home directory. If Joe was to change directories (cd) to say /boot/grub, then his prompt would now change too to show the new working directory.

joe | archlinux~:$ cd /boot/grub

joe | archlinux/boot/grub:$

Again, pretty neato, huh? This way, Joe will always know what directory he’s in at any given time. That will help prevent Joe from making any command line boo-boos.

That’s it, guys and gals. Pretty simple stuff. See? You’re not near as scared of that mean ol’ command line as you used to be, huh? Use your imagination when customizing your prompt. I’ve seen some pretty cool ones out there. Here’s the one my friend securitybreach and fellow Admin from Scot’s Newsletter Forums – Bruno’s All Things Linux uses:

╔═ comhack@Cerberus 02:27 PM
╚═══ ~/->

How’s that for spiffy? For further reading see HERE and HERE.

Have a great weekend wherever you may be!

~Eric


An Introduction to the Linux Shell

She sells seashells by the seashore. Well, yes… that may be true, but that’s not the type of shell we’re going to talk about here today.

I’m going to talk a bit about the Linux shell. What is the Linux shell? What does it do? How can I interact with it on my GNU/Linux operating system? Those are all good questions. While today’s most popular distributions of GNU/Linux are morphing into operating systems that are more and more graphic user interface oriented, the real power of Linux still resides in the command line.

When you boot up your Ubuntu or Mandriva GNU/Linux operating systems, most of you see a graphical login screen. Others, like myself, might see a non-graphic command line login. Both do basically the same thing. They log the user into the Linux shell so that he may begin to utilize his system’s potential to perform tasks. That’s what we do with our computers, regardless of what the tasks happen to be… emailing pics to auntie Myrtle or hacking cloud and cluster security systems.

The Linux shell is the interface between you in that seat in front of your monitor and the operating system that controls the hardware in that box under the desk that does the actual stuff you want done. There are numerous shells in Linux; the most commonly used one is called BASH – Bourne Again Shell. You’re in the shell anytime you’re logged into your GNU/Linux operating system; whether you’re interacting with it graphically or from the command line.

Graphic User Interfaces or GUIs are just “front ends” to applications that are running in the shell. I’ll be talking mostly about the non-graphical command line interface here today, though. You can access your command line interface from within your GUI by using the graphic front end application for the command line provided by your desktop environment. For example, in Gnome, you could use Gnome Terminal; or in KDE, you could use Konsole. Either way, these are both just graphical front ends for the BASH shell command line.

When you first login, you’ll get what’s known as a prompt. It is just a blank line waiting for your input (commands). It’ll look something like this:

joe@mysystem:~$

The first part, “joe”, is just the user’s login name. “@mysystem” is the name of the computer the user is logged into. The “~” character tells us that user Joe is working from his home directory. The “$” character is the standard character denoting a non-root, regular user.

Let’s say Joe wants to list all the files in his home directory. All he has to do is type:

joe@mysystem:~$ ls

This command, known as “list”, tells the shell that user Joe wants to see a list of all the contents of his home directory. The shell immediately responds after Joe hits the Return (Enter) key on his keyboard with this output:

Desktop  joe_archives  joe_common     joe_private
Dropbox  joe_backups   joe_downloads

It looks like Joe has five regular directories, a Dropbox directory, and the directory that contains his desktop icons. In reality, there are more directories and files in Joe’s home directory, but they’re what are known as “hidden” files. Their names are usually preceded by a .(period) to make them hidden. If joe wants to see all his directories and files he can list them this way:

joe@mysystem:~$ ls -a

The “-a” option means all. The list command will list all items in a directory when using the -a option. Joe’s list now looks something like this:

.dropbox        .macromedia      .thunderbird
.ICEauthority           .esd_auth    .moz_icons      .viminfo
.PySolFC           .fontconfig    .mozilla      .wicd
.Xauthority           .gconf        .mozilla_3.x      .xchat2

The above directories are hidden by the preceding .(period), as mentioned above.

Let’s say Joe want’s to create a grocery list for his afternoon shopping chores. He can do this via the shell and command line also by using a command line editor such as vim. He would first do this by bring up the vim application in the command line interface:

joe@mysystem:~$ vim groceries

This command would initiate the vim application using a new file called “groceries”. Vim or Vi-Improved, as it’s known, is a non-graphical text editing application. It would look something like this to Joe:

lettuce

tomatoes

catfood

peanut butter

eggs

milk

bread

~

~

~

–INSERT–                                                 10,1          All

Once Joe had finished typing out his grocery list, he would save it using the vim command :wq, which would also close the vim application and bring Joe back to the command line prompt. He could also print his list from the command line like this:

joe@mysystem:~$ lpr groceries

The lpr command would tell the shell that Joe wants to output the contents of the groceries file to the printer. The printer would receive the data and the command to print from the computer’s hardware and begin printing Joe’s grocery list.

All of this we’ve talked about today doesn’t even scratch the surface of the power at your finger tips when using the Linux shell. Your first step should be to read the Linux manual page for the BASH shell. There is some very useful information in that document. Stay tuned here… I’ll come up with some other lessons in the future. Remember what I always say…

Learn something. It won’t hurt you none. I promise.

Later…

~Eric

*This was previously posted on my old Nocturnal Slacker (@LockerGnome) blog and on the Community Blogs at Linux.com. I’m reposting it here to keep the series all in one place.