Please enable JavaScript eh!

 ⌘ Web Mechanic ⌘ 

Bash Scripting


Fundamentals

Open a terminal window so you can practice.
You may have to juggle the windows around so you can see this window and Terminal at the same time.

Here are some fundamental commands we will cover first.
  1. help
  2. man
  3. pwd
  4. whoami
  5. cd
  6. ls
  7. clear
  8. history

When you first run Terminal the text you see is called the prompt because it is 'prompting' you to enter a command.

It also indicates a few things which we will cover later, but for now just acknowledge it.

My prompt consists of 2 lines of text:

2024-09-02 13:18:27
[~] trudge:

It tells me a few things:

2024-09-01 13:46:23
  This is the current date and time, so obviously changes
[~]
  This is the current directory I am working in
  That funny squiggle (tilde) character is a short form for your home directory
trudge:
  This is who I am logged in as (my user name)

Your prompt will look a little different, but you can modify it so don't worry about it right now.

help

Probably the first command you might want to try out. It will list a brief description of all available builtin commands (and even some code structures) that you will need to know. If you give it a command name as an argument it will show usage of that command.

help help
help: help [-s] [pattern ...]
    Display helpful information about builtin commands.  If PATTERN is
    specified, gives detailed help on all commands matching PATTERN,
    otherwise a list of the builtins is printed.  The -s option
    restricts the output for each builtin command matching PATTERN to
    a short usage synopsis.

The commands are listed in 2 columns:

help
GNU bash, version 5.3.3(1)-release (aarch64-apple-darwin24.4.0)
These shell commands are defined internally.  Type `help' to see this list.
Type `help name' to find out more about the function `name'.
Use `info bash' to find out more about the shell in general.
Use `man -k' or `info' to find out more about commands not in this list.

A star (*) next to a name means that the command is disabled.

 ! PIPELINE                                                  history [-c] [-d offset] [n] or history -anrw [filename]>
 job_spec [&]                                                if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMAN>
 (( expression ))                                            jobs [-lnprs] [jobspec ...] or jobs -x command [args]
 . [-p path] filename [arguments]                            kill [-s sigspec | -n signum | -sigspec] pid | jobspec .>
 :                                                           let arg [arg ...]
 [ arg... ]                                                  local [option] name[=value] ...
 [[ expression ]]                                            logout [n]
 alias [-p] [name[=value] ... ]                              mapfile [-d delim] [-n count] [-O origin] [-s count] [-t>
 bg [job_spec ...]                                           popd [-n] [+N | -N]
 bind [-lpsvPSVX] [-m keymap] [-f filename] [-q name] [-u >  printf [-v var] format [arguments]
. . .
 for (( exp1; exp2; exp3 )); do COMMANDS; done               variables - Names and meanings of some shell variables
 function name { COMMANDS ; } or name () { COMMANDS ; }      wait [-fn] [-p var] [id ...]
 getopts optstring name [arg ...]                            while COMMANDS; do COMMANDS-2; done
 hash [-lr] [-p pathname] [-dt] [name ...]                   { COMMANDS ; }
 help [-dms] [pattern ...]

To get help on a command:

help fg
fg: fg [job_spec]
    Place JOB_SPEC in the foreground, and make it the current job.  If
    JOB_SPEC is not present, the shell's notion of the current job is
    used.

man

No, that's not some kind of gender-based allusion. As you may know, programmers are somewhat lazy typists. That command shows you the 'manual' for a particular builtin command.

'Builtin' commands are part of the bash shell, NOT individual files. You should be able to get a list of these commands:

compgen -b
.
:
[
alias
bg
bind
break
builtin
caller
cd
command
compgen
complete
compopt
...
true
true
type
typeset
ulimit
umask
unalias
unset
wait

Programming in bash uses both builtin and external commands.

The 'man' for 'ls' begins thus:

LS(1)                                           General Commands Manual                                          LS(1)

NAME
     ls – list directory contents

SYNOPSIS
     ls [-@ABCFGHILOPRSTUWabcdefghiklmnopqrstuvwxy1%,] [--color=when] [-D format] [file ...]

DESCRIPTION
     For each operand that names a file of a type other than directory, ls displays its name as well as any requested,
     associated information.  For each operand that names a file of type directory, ls displays the names of files
     contained within that directory, as well as any requested, associated information.

     If no operands are given, the contents of the current directory are displayed.  If more than one operand is
     given, non-directory operands are displayed first; directory and non-directory operands are sorted separately and
     in lexicographical order.

     The following options are available:

To determine whether a file is builtin or something else use 'type':

type ls fg declare whois man
ls is /bin/ls
fg is a shell builtin
declare is a shell builtin
whois is /usr/bin/whois
man is hashed (/usr/bin/man)

pwd

A very important thing to know when you are working in Terminal is where you are in the file system. If you execute a command in the wrong place you may not see the results immediately, but it is probably NOT what you intended to do. (This is the 'risky' part mentioned earlier)

pwd stands for print working directory (not password)
and it DOES tell you where you are in the file system.

bash commands are case-sensitive and space-sensitive
Every character counts
Every letter, space, quote, hyphen,
., +, -, *, =, \, %, /, $, |, and @
will affect how bash interprets your commands

There is no "Are you sure?" in bash

So, type  pwd  at the prompt and hit the 'enter' key.

2024-09-01 13:46:23
[~] trudge: pwd
/Users/trudge
2024-09-01 13:46:41
[~] trudge:

When I typed 'pwd' at my prompt, it came back with the response:

/Users/trudge

That tells us that we are in the /Users/trudge directory, which is where I was at the time. Your result may be different.

whoami

Yes, this is really a command. Can you guess what it does?

Correct - it tells you what user you are logged into bash as. We want to make sure we are not logged in as 'root'.

Apple changed the way it organizes Application files with Catalina 10.15.
This link explains.

In short, there are 2 locations for your applications:
• one for System Applications
• one for applications you have installed (even Safari since it's odd)

In the following sections I will assume your computer is updated to at least Catalina (10.15), and the commands presented reflect that assumption.

cd

This command is short for change directory. If you type cd by itself it does something special.
It changes to your Home directory automatically.

2024-09-02 13:34:35
[~/httpd/terminal] trudge: cd
2024-09-02 13:34:40
~ trudge:

I was in '~/httpd/terminal' initially, but now I am in '~' - my Home directory.

That funny squiggle character (tilde) ~ is an alias for your home directory.

To use cd, we need to give it an argument (no, not that kind) and tell it where we would like to be.

See this link for more about directories and paths

So in Terminal type cd /System/Applications

[~/httpd/terminal] trudge: cd /System/Applications
2024-09-02 13:49:08
[/Applications] trudge:

Notice we did not add the tilde character (squiggle) ~ at the beginning, but a front slash /.

OK, so we're in the /Systems/Applications directory. So what? Good question.

The next command will help us with that.

 Options & Arguments 

Some commands we will be talking about here allow us to include additional information - these are known as options and arguments:
• Options are typically entered directly after the command and usually begin with a hyphen (-)
  They affect how the command behaves
• Arguments are typically entered after any options
  They affect WHERE or WHAT the command acts on, but may not always be needed

ls -1

That is the ls command, a space, a hyphen and the digit 1

This command stands for list and will list the files contained in a directory. The option '-1' will list each file on a single line.

Like the cd command it can optionally take an option and an argument or not. Without an argument, it lists the files in the directory you are currently in.

Since we are in the /System/Applications directory, what does it tell us?

2024-11-27 13:27:58
[/System/Applications] trudge: ls -1
App Store.app
Automator.app
Books.app
Calculator.app
...
Time Machine.app
Utilities
VoiceMemos.app
Weather.app
2024-11-27 13:30:32
[/System/Applications] trudge:

As you can see it shows a sorted list of files in the current directory.

But (you knew there was a but, right?) there is a lot more data available. Two useful options are a (all) and l (long) like so:

2024-11-27 13:30:32
[/System/Applications] trudge: ls -al
total 0
drwxr-xr-x  43 root  wheel  1376 Aug  4 06:31 .
drwxr-xr-x@ 10 root  wheel   320 Aug  4 06:31 ..
-rw-r--r--  15 root  wheel     0 Aug  4 06:31 .localized
drwxr-xr-x   3 root  wheel    96 Aug  4 06:31 App Store.app
drwxr-xr-x   3 root  wheel    96 Aug  4 06:31 Automator.app
drwxr-xr-x   3 root  wheel    96 Aug  4 06:31 Books.app
drwxr-xr-x   3 root  wheel    96 Aug  4 06:31 Calculator.app
drwxr-xr-x   3 root  wheel    96 Aug  4 06:31 Calendar.app
drwxr-xr-x   3 root  wheel    96 Aug  4 06:31 Chess.app
drwxr-xr-x   3 root  wheel    96 Aug  4 06:31 Clock.app
drwxr-xr-x   3 root  wheel    96 Aug  4 06:31 Contacts.app
...
drwxr-xr-x   3 root  wheel    96 Aug  4 06:31 System Settings.app
drwxr-xr-x   3 root  wheel    96 Aug  4 06:31 TV.app
drwxr-xr-x   3 root  wheel    96 Aug  4 06:31 TextEdit.app
drwxr-xr-x   3 root  wheel    96 Aug  4 06:31 Time Machine.app
drwxr-xr-x  22 root  wheel   704 Aug  4 06:31 Utilities
drwxr-xr-x   3 root  wheel    96 Aug  4 06:31 VoiceMemos.app
drwxr-xr-x   3 root  wheel    96 Aug  4 06:31 Weather.app
2024-11-27 13:53:47
[/System/Applications] trudge:

Well, that's quite a bit of information. Notice there are about 9 columns. You may have to widen the Terminal window to view it correctly.

Here is what each column tells us:

drwxr-xr-x   3 root  wheel    96 Aug  4 06:31 Calculator.app
• drwxr-xr-x
  file type, with 3 sets of permissions each for Owner, Group, World: read-write-execute
  'd' as the 1st character represents a file type of directory
  may also have Access Control characters (@,+)
• 3
  number of links to this file
• root
  owner of the file
• wheel
  group of users the file belongs to
• 96
  size of the file in bytes
• Aug 4 06:31
  3 columns (6,7,8) when the file was last changed
• Calculator.app
  name of the file (recall that a directory is just a type of file)

This link will give you more details about what they all mean.

More about Access Control Lists

Also note that while these are Applications, they are listed as directories. This is a bit beyond your pay scale at this point, but we will return to this later. For now check the Resources page for Application Bundles.

In the above example using the ls command we included the option -1 (that is a digit 1, not a lower-case l). But we did not include an argument.

Without an argument, the default action for this command (and many others) is to access files in the current directory.

To list files in a different directory, we would include that as an argument:

2024-11-27 16:38:58
[~/httpd/bash] trudge: ls -1 ~
Applications
Calibre
Desktop
Documents
Downloads
Fonts
Library
Movies
Music
MyDB
Pictures
Public
Sites
_.bash_rc
bin
httpd

Here, we used the -1 option again, and included an argument ~, which if you recall, means your Home directory.

Commands that can take an argument include
• cd
• ls
• cp
• mv
• mkdir
• rm
• rmdir
• touch
• cat

clear

When you find the Terminal window gets too cluttered and confusing, this command will clear the screen (DUH).

history

As you might have guessed, this command will present a list of all the previous commands you have entered in the current session of bash. This is very handy when you need the same command again, but need to edit something first.

Here are the last 5 commands I entered:

  500  cd /Users/trudge/MyDB
  501  ls -ale
  502  chmod u=w steam.db
  503  ls -ale
  504  history

They are numbered, which means we can specify a particular command we want to execute again.

Here's a few things you can do with history:
• history N
  print the last N commands
• history -c
  clear (delete) the history
• !!
  run the previous command again
• !N
  run command #N again
• !-N
  run the command N commands ago

history Navigation

bash keeps track of the commands you have typed (the history of the current session). They are available when you press the Up Arrow and the Down Arrow keys. Get familiar with this way of seeing the history of your session. You can bring up the last command you entered and even make changes in it if you need.

touch | mkdir