MoonPoint Support Logo


Shop Amazon Warehouse Deals - Deep Discounts on Open-box and Used ProductsAmazon Warehouse Deals

Advanced Search
Sun Mon Tue Wed Thu Fri Sat
21 22 23 24 25 26 27
28 29 30        
AprMay Jun
Jul Aug Sep
Oct Nov Dec

Tue, Jan 01, 2019 10:42 pm

Creating new directories for a new year

I have a number of log directories where I store log files where the directory name is the current year. On the last day of the old year, I want to create new directories named for the upcoming year. I use the following Bash script to create those directories. Since I have several email log directories, I use a for loop to create a directory named after the upcoming year in each one.

# Create a new directory corresponding to the upcoming year on December 31 of
# every year

newyear=$(date --date=tomorrow +%Y)
echo $newyear

# Apache logs

# Check on whether the directory for the current year exists and, if it doesn't,
# create it.
if [ ! -d /home/jdoe/www/logs/apache/"$newyear" ]; then
   mkdir /home/jdoe/www/logs/apache/"$newyear"
   chown apache /home/jdoe/www/logs/apache/"$newyear"
   chgrp apache /home/jdoe/www/logs/apache/"$newyear"

# Email logs 

# Create an array holding the names of the 4 directories within which
# subdirectories will be created using the name of the new year. E.g.,
# /home/jdoe/www/logs/mail/sendmail_stats/2019

logdirs=( "dnsbl_count" "sendmail_stats" "smlogstats" "smreject"  )

for i in "${logdirs[@]}"
do :
   # Check on whether the directory for the current year exists and, if it 
   # doesn't, create it.
   if [ ! -d /home/jdoe/www/logs/mail/$i/"$newyear" ]; then
      mkdir /home/jdoe/www/logs/mail/$i/"$newyear"
      chown jdoe /home/jdoe/www/logs/mail/$i/"$newyear"
      chgrp jdoe /home/jdoe/www/logs/mail/$i/"$newyear"

I then have a crontab entry containing the following line that will result in the Bash script above, named end-of-year-dirs, being run at 7;00 AM on December 31 of each year.

0 7 31 DEC * /root/bin/end-of-year-dirs

Related articles:

  1. Loop through an array in Bash
  3. crontab -e
  4. smlogstats

[/os/unix/bash] permanent link

Thu, Sep 07, 2017 10:38 pm

Looping over a set of files in the Bash shell on Linux or OS X

I have a Python script,, that takes a file name as a parameter. I use the script to identify if a file with a .bin extension is actually a Microsoft Visio or PowerPoint file. I run the script on an OS X system from a Terminal window where I have a Bash shell prompt. E.g.:

$ ~/Documents/bin/ oleObject1.bin
Microsoft Office PowerPoint

But I often want to have it check all of the .bin files in a directory. You can loop through all files in a directory or a set of files using a Bash for loop. E.g., to check all of the .bin files in a directory I could use the for-loop below:

$ ls *
oleObject1.bin	oleObject3.bin	oleObject5.bin
oleObject2.bin	oleObject4.bin	oleObject6.bin
$ for f in *.bin; do ~/Documents/bin/ $f; done
Microsoft Office PowerPoint
Microsoft Office PowerPoint
Microsoft Office PowerPoint
Microsoft Visio
Microsoft Visio
oleObject6.bin: CDF V2 Document, No summary info


[ More Info ]

[/os/unix/bash] permanent link

Sun, Jan 01, 2017 8:45 pm

Determining if a directory exists in a Bash script

I have a Bash script that copies the prior day's mail log file from /var/log/maillog.1 to another directory for archiving. The archive directory contains a subdirectory for each year's mail logs. Today is the first day of a new year, so I needed to create a 2017 directory. I could manually create the directory, but I thought I'd modify the Bash script that runs from Cron to check on whether the current year's directory exists and, if it doesn't create it, so, if I forget in future years to create a new year's directory the script will create it for me.

You can check if a directory exists with code similar to what is shown below:

if [ -d "$DIRECTORY" ]; then
  # Insert code to be executed

Or, to check if a directory doesn't exist and execute commands if it doesn't:

if [ ! -d "$DIRECTORY" ]; then
  # Insert code to be executed

Note: putting the $DIRECTORY variable in double quotes allows for cases where the directory name may contain a space. Though that won't be the case for my yearly subdirectories, it is something you can allow for by enclosing the variable name in double quotes.

[ More Info ]

[/os/unix/bash] permanent link

Mon, May 09, 2016 11:25 pm

Creating a Bash menu

You can create a menu of options for someone to choose from in a Bash script using the select construct. E.g., the following Bash script will present a text-based menu with three choices: "Option 1", "Option 2", and "Option 3".

# Bash Menu Script Example
PS3='Please enter your choice: '
options=("Option 1" "Option 2" "Option 3" "Quit")
select option in "${options[@]}"
case $option in
"Option 1")
echo "You chose option 1"
"Option 2")
echo "You chose option 2"
"Option 3")
echo "You chose option 3"
echo "Quitting the program"
*) echo invalid option;;

Note: to make a script executable from your account, you must set the file permissions for the script to grant execute permission for your account, e.g. with chmod u+x menu, if the file name for the script was named menu.

When the script is run, it will display the following text:

1) Option 1
2) Option 2
3) Option 3
4) Quit
Please enter your choice:

If the person running the script types "1", the script will display "You chose option 1". It will display "You chose option 2", if he/she types "2", "You chose option 3", if he/she types "3" and, if he/she types "4", will display "Quitting the program" and then exit from the script. Hitting any other key will cause the script to display "invalid option" while allowing the user to type another key for one of the other options.

By setting the PS3 variable you can control the prompt that is displayed to the user. If it wasn't set, the user would see a default prompt, which is #?, displayed, instead, as shown below:

1) Option 1
2) Option 2
3) Option 3
4) Quit

The select construct has the following format:

select Word in Array

Word and Array are names of your choosing. If you are unfamiliar with what an array represents, think of it as a collection of items. You can think of it as a list, though in computer programming languages those are not necessarily synonymous. You can find more information at Bash Arrays.

In the example above, I chose "Option" for Word and "Options" for the array name. The array, i.e., the list of options, was created with the following command:

options=("Option 1" "Option 2" "Option 3" "Quit")

The first element of the array, which contains 4 elements in this case, is "Option 1", the next "Option 2", etc.

The ${options[@] in select option in "${options[@]}" returns each item in the array as a separate word.

Between the case $option in and esac (case reversed), I can insert the commands to be carried out for each option that is selected. Including a *) allows the script to take some action when any key not associated with a valid option is typed. Each clause in the case statement must be terminated with ";;". Each case statement is ended with the esac statement. For further information on the case statement, see Using case statements in Machtelt Garrels Bash Guide for Beginners.

Bash is a common shell on Unix and Linux systems and is the default shell when you open the Terminal application on a Mac OS X system. And even Microsoft has announced that it will provide a Bash shell in the Windows 10 Anniversary Update, which is expected to be shipped this summer. So you can create text-based menus using this method on a variety of operating systems.

[/os/unix/bash] permanent link

Wed, Jan 13, 2016 11:24 pm

Returning to a prior directory with Bash

If you use the Bash shell on a Unix/Linux system, you can return to the prior directory you were in using cd $OLDPWD or simply cd -. If you wish to be able to easily return to a prior directory further back, you can use the pushd and popd commands. The pushd command pushes the current directory onto a directory stack,i.e., each time you issue the command the current directory is added to the "top" of the stack. When you issue the popd command, you are returned to the directory that is currently at the top of that stack. So if you were in the directory /home/jdoe/test then issued the command pushd, later changed the working directory to /home/jdoe/abc and issued the command pushd again then the command cd /home/jdoe/def followed later by cd /home/jdoe/ghi, if you then issued the command popd, your current working directory would become /home/jdoe/abc. If you entered the popd command a second time without any intervening pushd command, you would be returned to directory /home/jdoe/test, the first directory pushed onto the stack.

[/os/unix/bash] permanent link

Tue, Oct 15, 2013 10:40 pm

Deleting a command from your bash history

The bash shell is a commonly used shell on Unix/Linux systems. The history feature which is available with the bash shell is very useful, allowing you to easily recall and reuse previously entered commands without retyping them. E.g., if you had entered a long ssh command with a lot of options, you can simply hit Ctrl-R and type ssh to recall the last ssh command entered. You can then edit the command or simply hit Enter to execute the same command again.

Occasionally, though, you may not want something you've typed at the shell prompt to remain in your history file. E.g., I've occasionally inadvertently typed a password at a point where a password prompt hadn't appeared. You can delete a particular command by using history -d num where num is the number assigned to the command in the history file, which you can see by typing history with no parameters. After deleting the command use history -w to write the update to your ~/.bash_history file to disk. E.g., If I saw that command 245 was showing the password I mistakenly typed, I could use the following commands to ensure that the password couldn't be viewed by anyone who might gain access to the history information:

$ history -d 245
$ history -w

If you wished to delete all the commands stored in the history file, you could use history -c followed by history -w.

[/os/unix/bash] permanent link

Thu, Sep 08, 2011 9:33 pm

Bash Calculator

If you need to do quick calculations on a system that provides the Bash shell, such as Linux or Mac OS X, you can perform calculations by using the echo command and then using $[ and ] to enclose the arithmetic calculation, i.e., echo $[calculation to be performed]. You can use the standard arithmetic operators of + for addition, - for subtraction, * for multiplication, / for division, and ** for exponentiation.
$ echo $[1+1]
$ echo $[9*90]
$ echo $[81/9]
$ echo $[2**3]

The standard precedence for operators applies, i.e., multiplication and division have precedence over addition and subtraction, so are performed first, i.e., the calcuations are not simply done on a left to right basis.

$ echo $[2+3*4]
$ echo $[6-4/2]

This Bash calculator functionality even handles negative numbers appropriately.

$ echo $[-4*5]
$ echo $[-4*-5]


  1. When you need a quick & simple calculator in Bash...
    TinyApps.Org, small is beautiful
  2. Bash (Unix shell)
    Wikipedia, the free encyclopedia

[/os/unix/bash] permanent link

Mon, Dec 29, 2008 2:57 pm

Chopping Strings in BASH

The Bourne-again Shell (BASH) provides built-in mechanisms for extracting substrings from a string.

You can set the value of a variable with myvar="some text". You can view the value of the variable using $myvar or ${myvar}. Putting the "$" in front of the variable name causes BASH to use the value stored in myvar.

$ myvar="some text"
$ echo $myvar
some text
$ echo ${myvar}
some text

There is sometimes an advantage to the format that encloses the variable name in curly braces, i.e. the ${myvar} format.

$ echo "foo$myvar"
foosome text
$ echo "foo$myvarother text"
foo text
$ echo "foo${myvar}other text"
foosome textother text

In the above example, in the instance where the curly braces weren't used, the value of myvar wasn't displayed, because BASH didn't know I wanted myvar rather than myvarother, which has no value assigned to it, so it just dispalyed "foo text". In the second instance where the curly braces were used, BASH could tell I wanted the vaue of myvar and displayed "foo some textother text".

Substrings can be extracted from a string by chopping characters from the beginning and end of a string.

Chopping a trailing character:

You can chop a trailing character from a string in BASH by placing the variable name inside ${ }, such as ${myvar}, and then using %<char>. E.g. suppose myvar has the value "0064092004008999,". To remove the trailing comma from the end of the variable, you could use myvar=${myvar%,}

$ myvar="0064092004008999,"
$ echo ${myvar%,}

If you wanted to remove the last "9" and all characters that appear after it in the line, you can use "*" in the expression.

$ myvar="0064092004008999,"
$ echo ${myvar%9*}

In the example above, the shortest matching substring is selected and removed, i.e. the "9,". If you wanted to remove the longest matching substring, e.g. every character from the first "9" onwards, you could use

$ myvar="0064092004008999,"
$ echo ${myvar%%9*}

Chopping leading characters:

You can chop leading characters from a string by using # or ##. E.g. suppose myvar has the value "SNMPv2-MIB::sysContact.0 = STRING: John Smith". If you only want the name John Smith, you can use ## to remove the longest substring containing the ":" character. I.e., using myvar=${myvar##*:} wold work. If you instead used only one "#", the shortest matching substring would be removed. I.e., using myvar=${myvar#*:} would return :sysContact.0 = STRING: John Smith, where all characters up to and including the first ":" are removed.

$ myvar="SNMPv2-MIB::sysContact.0 = STRING: John Smith"
$ echo ${myvar##*:}
John Smith
$ echo ${myvar#*:}
:sysContact.0 = STRING: John Smith


  1. Bash by example, Part 1
    Fundamental programming in the Bourne again shell (bash)
    Date: March 1, 2000

[/os/unix/bash] permanent link

Sun, Mar 05, 2006 10:53 am

BASH Variables

Some useful variables available in the BASH shell.



if [ $# -eq 0 ]
  echo "Usage: $0 filename"
  wc -l $1

The script first checks for whether any argument has been entered on the command line, i.e. whether $# equals zero. If no arguments are present on the command line, the script prints a usage message. The $0 variable holds the name of the script itself. If an argument is entered on the command line, it is presumed to be a filename and the wc command is called to count the number of lines in the file.

So, if the script is named "example", and is called without any options, then the following output would be printed.

# ./example
Usage: ./example filename

If a filename is entered on the command line and that file has 21 lines in it, the following would be printed.

# ./example sample.txt
     21 sample.txt


  1. Linux Shell Programming

[/os/unix/bash] permanent link

Fri, Jul 29, 2005 6:17 pm

Bash Tips

I normally use the bash shell on Unix and Linux systems. A shell is the user interface to the system. The shell on Unix and Linux systems gives you the type of interface you get with a command prompt on Windows systems. On older versions of Windows you would be issuing DOS commands at the command prompt. As you have batch files with DOS, with Unix and Linux shells you can create scripts to automate your work, though you normally get a much richer set of commands than with DOS.

Prior to the development of the bash shell there was a Bourne shell and the name Bourne Again Shell (bash) comes from the name of that prior shell. The bash shell was created by Brian Fox in 1988. He continued to work on it until 1993. Chet Ramey joined Brian in the development of bash in 1989 and Chet continued the work on bash after Brian ceased his development efforts on bash.

I've posted a few bash tips in Bash Tips

[/os/unix/bash] permanent link

Valid HTML 4.01 Transitional

Privacy Policy   Contact

Blosxom logo