Linux Blog

Automated scanning with the shell

Filed under: Shell Script Sundays — TheLinuxBlog.com at 9:25 am on Sunday, July 27, 2008

I recently needed to scan a lot of images on my desktop PC. Unfortunately I am not the owner of an automatic document feed printer, and if I were it wouldn’t have helped this time because the documents I needed to scan were not feed able. XSANE is a great way to scan documents visually in Linux. Its not the easiest to use, but it has plenty of options. Part of the SANE package is scanimage, scanimage can be used from the shell.

The first thing that I did was a few test images with scanimage. I quickly found out that scanimage outputs in pnm format, and at a high resolution if the correct options are used. Once I found out the good options for my scanner (scanimage –resolution 400 > file.pnm) I wrote a quick shell script to scan up to 1000 times or until I don’t give the script any input. To do this, I used a combination of snippets that can be found in this blog column.

Here is a direct link to the script, and the shell script source below

#!/bin/bash
for i in `seq 1 1000`; do

#get input line
read inputline;

if [ $inputline ]; then

#Process Scanned Image in BG
echo Scanning Pg$i;
scanimage –resolution 400 > Pg$i.pnm;
echo Next;
else
exit
fi

done;

To use it all I do is execute the script, and I get to scan up to 1000 documents providing I type something after it prompts “Next”, and then hit enter. Once I was done scanning, I just hit enter to stop the script execution and then moved on to manipulating the images with the shell.

Hope this shell script scanning script is useful, if it is then drop me a comment, or if you have any suggestions or it was not at all helpful still drop me a comment.

Suspend Scripts for the Toshiba Tecra M2

Filed under: Quick Linux Tutorials,Shell Script Sundays — TheLinuxBlog.com at 12:15 am on Sunday, March 30, 2008

As you may know if you are a regular reader I own a Toshiba Tecra M2. One of the things that annoyed me was I had to turn the brightness up every time my computer came out of standby mode. A fix for this is to adjust the brightness every time the computer comes out of standby mode.

The script is intended to be run under cron. I have mine set up to suspend after 5 minutes of the lid being closed.

if [ $(cat /proc/acpi/button/lid/LID/state | sed 's/state:      //') == "closed" ]; then
VAR=$(cat /proc/acpi/toshiba/lcd | sed ‘s/brightness:              //’ grep -v levels);
sudo su -c “echo mem > /sys/power/state”;
if [ $VAR -eq 1 ]; then
ACTION=ADD;
elif [ $VAR -eq 7 ]; then
ACTION=SUB;
else
ACTION=ADD;
fi;
if [ $ACTION == "ADD" ]; then
VAR=$(($VAR + 1));
else
VAR=$(($VAR – 1));
fi;
sudo su -c “echo brightness:$(echo $VAR) > /proc/acpi/toshiba/lcd”;
fi;

I run this with the following cron entry:

*/5 * * * * sh hibernate.sh

The script first checks the current brightness. If the brightness is currently 1 or 7 it adjusts the mathematic operation so that when the laptop is opened the brightness is adjusted. Basically if the brightness is one, it adds one. If the brightness is 7 or any other value it subtracts one. This is currently working out quite well for me. I don’t know how useful this is to any body else, unless you happen to have a Toshiba that is doing the same thing but it should give you a good overall idea of how to perform basic mathematic operations in bash.

Bin and Cue Support for Linux

Filed under: Quick Linux Tutorials — TheLinuxBlog.com at 2:35 pm on Tuesday, March 18, 2008

If you have a bin/cue image that you need to use under Linux you may be in for a surprise. I recently downloaded a copy of a game that I owned but was too scratched to use. The problem was the game came in bin / cue format. To fix this I just used a nifty little program called bchunk and converted it to ISO. It can be found here: http://he.fi/bchunk/

I would really like to find a way to mount bin and cue images under Linux but so far I’m not having any luck. I’m wondering if with some modification the bchunk program could be used with fuse.

Shell Script to get user input

Filed under: Shell Script Sundays — TheLinuxBlog.com at 2:06 am on Sunday, January 27, 2008

Creating a shell script to get input is rather easy. Shell scripts prompting input are generally more user friendly too. In this article I’ll show you how to read input from the bash shell. Take the example below:

#!/bin/bash

echo "Shell Script To Get User Input";

while read inputline
do
what="$inputline"
echo $what;

if [ -z "${what}" ];
then
exit
fi

done

All it does is echo’s the introduction “Shell Script To Get User Input” and then goes right to the bash read input loop. The next line makes a variable so that we can echo it out and also check if its empty with the if [ -z part. If the script is empty we exit, if not we loop around another time.

This is a very basic example but it can easily be modified so that you can use bash to grab user input. If you have any trouble with this script drop me a comment and I’ll be happy to help you out.

Making your scripts user and sysadmin friendly

Filed under: Shell Script Sundays — TheLinuxBlog.com at 11:08 pm on Sunday, November 18, 2007

When designing a shell script it is important to make them easy to use but also to make it easily automated for deployment. One example of this that comes to mind is the NVIDIA installer. It has command line options to allow for deployment but also gives a nice interface for the end user.

To implement this “dialog” can be used for the user interface and “getopts” can be used for the command line options. The script may look something like:

#help function
help () {
echo “Linux Blog – getopts and dialog example”;
echo “Usage:”;
echo -e “\t -h shows this help”;
echo -e “\t -a [y/n][other] ANSWER (Yes, No or Other)”;
}

#show dialog to get the answers
showDialog () {
dialog –yesno “Do you want to enter y?” 5 50 && \
ANS=”Yes was entered using dialog” ||\
ANS=”No was entered using dialog”
showAnswer;
}

#actually show the answer
showAnswer() {
echo $ANS;
}

#check answer for command line processing
checkAns() {
if [ "${OPT1}" == "y" ]
then
ANS=”Yes sent by getopts”;
elif [ "${OPT1}" == "n" ]
then
ANS=”No was sent getopts”;
else
ANS=”This: $OPT1 was sent by getopts”;
fi
#call showAnswer
showAnswer;
}

#get the options
while getopts “a:h” ARG;
do case “${ARG}” in
a) OPT1=”${OPTARG}”;;
h) HELP=”TRUE”;;
esac;
done

#see if help was entered
if [ "${HELP}" ]
then
#display help and quit
help;
exit;
fi
#if the options are empty
if [ -z "${OPT1}" ]
then
showDialog;
else
checkAns;
fi

Keep this getopts and dialog post in mind next time your shell scripting. It will take a little extra time to implement but the result will be a user and sysadmin friendly script.

For, While and Until Loops in Bash

Filed under: Shell Script Sundays — TheLinuxBlog.com at 3:45 pm on Sunday, August 12, 2007

Normally in a shell script it is desirable to do something repetitive.
I have touched on some loops in other posts but now would like to go over them in a bit more detail. Each of the examples in this post are intended to give an introduction to looping in bash.

For Loops
For loops allow you to repeat a section of code a number of times. Its very similar to other languages syntax but works a little differently. The for loop in bash only allows you to give a fixed list of values to loop over. A good way to remember how a for loop works is “For each of the dishes: clean and dry.”
For Syntax:

for i [in list]
do
statements [use $i]
done

For Example:

for x in 1 2 3
do
echo “Number: $x”
done

echo “Finished!”

This is a very simple script that just counts to 3 and then prints “Finished!”

While and until Loops
In essence while and until are the same in bash. The titles are pretty much self explanatory. A while loop would be explained in real life as “While the sink is still full: wash dishes” and a until loop would be “Until the sink is empty: Wash dishes.”
While and Until Syntax:

until/while [condition] do
statements
done

Example of a While loop:

count=1
while [ $count -lt 10 ]; do
echo $count
let count=$count+1
done
echo “Finished!”

Basically this loop will loop over the code while the count variable is less than 10. If we didn’t put the let statement in the script it would get stuck in the loop causing the user to press CTRL+C to end the script.

Doing the same thing can be done in a until loop except the condition has to be modified to get the same result.
Until example:

count=1
until [ $count -gt 9 ]; do
echo $count
let count=$count+1
done
echo “Finished!”

Now that you’ve figured out how to loop over something its probably a good idea to know how to stop the loop.
All that needs to be done to stop a loop is:

break

Break Example:

for x in 1 2 3 4 5
do
if [ $x = 3 ]; then
echo “Number is 3. Quitting”
break;
fi
echo “Number: $x”
done

This is a very easy to follow example. Its the same as the basic for loop except that if x is 3 it will stop the loop. This example has no real practical purpose. Since its a for loop the number 3 could just have been omitted.

Real World For Loop Example
Looping over all files in /etc and printing all of those that match “grep conf” and putting them in quotes.
The code to do this in a loop is:

for x in $(ls /etc -1|grep conf);
do
echo “$x”
done

The situation for many bash scripts is that there is normally a shorter way to do something. Take the Real World For Loop Example in this tutorial the same results can be achieved with:

x=$(ls /etc |grep conf); echo “$x”\n

This will get the job done but a loop may be better for esthetic purposes or for additional logic.

Decision making in Bash If / Then / Else statements and Cases

Filed under: Shell Script Sundays — TheLinuxBlog.com at 3:44 pm on Sunday, August 5, 2007

There comes a time in every shell script where a decision has to be made.

To make a decision in bash the following if then else syntax can be used:

if [ condition ]
then

statements

[ elif [ condition ]

then

statements ]

[ else

statements ]

fi

Anything in non bold [ brackets ] is optional, and they should not be typed but the bold in them is required. Anything in bold must be typed. Statements are generally other commands or flow control statements.

To give an example of how to use bash if then else statements in the real world take the following scenario:

A system administrator has a strict habit of firing people that have too many .png files. He checks the systems regularly and makes sure that nobody has too many. The following script will display a message depending on the number of .png’s that are in the directory.

#!/bin/bash
gif_count=$(ls | grep .png | wc -l)
echo “Number of PNG’s: $gif_count”
if [ $gif_count -lt 10 ]
then
echo “He will be happy, you have less than 10 files”
elif [ $gif_count -gt 10 ] && [ $gif_count -lt 20 ]
then
echo “Consider deleting some files”
else
echo “you have too many files, DELETE SOME BEFORE HE FINDS OUT!”;
fi

Using Cases.

Cases are similar to if statements in that they match a expression and perform a task if the pattern is matched.

bash case syntax:

case expression in

pattern1 ) statements ;;

pattern2 ) statements ;;

esac

This is fairly simple and some people find this easier than doing if statements for simple logic. Take the following real world example:

The system administrator has recently gone on a bigger power trip than before. Since people got wise about using png’s and started saving images in other file formats he is now monitoring png’s gif’s and jpg’s. To combat the problem, you can use a case to count how many files you have of each type. (This is intended as an example, there are many ways to accomplish this task, this is just to demonstrate how cases work)

#!/bin/bash
#set all variables to 0
png=0
gif=0
jpg=0

# start loop
for wc in $(ls); do

case “$wc” in
*png ) let png=$png+1 ;;
*gif ) let gif=$gif+1 ;;
*jpg ) let jpg=$jpg+1 ;;
esac

# end loop
done

echo “Png’s $png”;
echo “gif’s $gif”;
echo “jpg’s $jpg”;

There you have it, two ways to make basic decisions in bash. Just figure out what you want to do then use an if then else, or a case statement to do the logic. I myself prefer if statements over cases as they make more sense to me and I find it easier to perform logic within ifs.

Programs used in this post
ls, echo, grep, wc