TOPIC: SHELL SCRIPT
Harnessing the power of ImageMagick
26th October 2008Using the command line to process images might sound senseless, only for the tools offered by ImageMagick certainly prove that it has its place. I have always been wary of using bulk processing for my digital photo files (some digitised from film prints with a scanner) but I do agree that some of it is needed to free up some time for other more necessary things. With this in mind, it is encouraging to see the results from ImageMagick and I can see it making a major difference to how I maintain my online photo gallery.
For instance, making thumbnail images for the gallery certainly seems to be one of those operations where command line bulk processing comes into its own, and ImageMagick's own convert command is heaven sent for this one. For resizing images, all that's needed is the following:
convert -resize 40% input.jpg output.jpg
Add a spot of further shell scripting and even a dash of Perl and the possibilities for this sort of thing become clearer, and this is but the pinnacle of the proverbial iceberg. The -rotate
switch will do what the name suggests, while there are a whole plethora of other options on tap. So long as you have Ghostscript on your system, conversion of graphics to Postscript (and Encapsulated Postscript too) and PDF files is possible with the -page
option controlling the margin around the image itself in the resulting outputs. Unfortunately, portrait is the sole orientation on offer, yet a bit of judicious post-processing will turn things around. Here's a command that'll do the trick:
convert -page 792x612+72+72 input.png ps2:output.ps
For retrieving image metadata like its resolution and size, the identify command comes into play. The -verbose
option invokes the output of all manner of image metadata, so using grep
or egrep
is perhaps advisable, especially for bulking processing with the likes of Perl. Having the ability to stream image metadata makes loading databases like MySQL less of a chore than the manual data entry that has been my way of doing things until now.
A quick way to create a blank text file
27th June 2008The primary job done by the touch command in UNIX or Linux is to update the time stamps on files. However, it also has another function: creating an empty text file where you are "touching" a file that doesn't exist. This has its uses, particularly when you want to reduce the amount of pointing and clicking that you need to do, or you want to generate a series of empty files in a shell script. Whatever you do with it is up to you.
Automating FTP II: Windows
15th April 2008Having thought about automating command line FTP on UNIX/Linux, the same idea came to me for Windows too, and you can achieve much the same results, even if the way of getting there is slightly different. The first route to consider is running a script file with the ftp command at the command prompt (you may need %windir%system32ftp.exe to call the right FTP program in some cases):
ftp -s:script.txt
The contents of the script are something like the following:
open ftp.server.host
user
password
lcd destination_directory
cd source_directory
prompt
get filename
bye
It doesn't take much to turn your script into a batch file that takes the username as its first input and your password as its second for the sake of enhanced security and deletes any record thereof for the same reason:
echo open ftp.server.host > script.txt
echo %1 >> script.txt
echo %2 >> script.txt
echo cd htdocs >> script.txt
echo prompt >> script.txt
echo mget * >> script.txt
echo bye >> script.txt
%windir%system32ftp.exe -s:script.txt
del script.txt
The feel of the Windows command line (in Windows 2000, it feels very primitive, but Windows XP is better and there's PowerShell now too) can leave a lot to be desired by someone accustomed to its UNIX/Linux counterpart, yet there's still a lot of tweaking that you can do to the above, given a bit of knowledge of the Windows batch scripting language. Any escape from a total dependence on pointing and clicking can only be an advance.
Filename autocompletion on the command line
19th October 2007The Windows 2000 command line feels an austere primitive when compared with the wonders of the UNIX/Linux equivalent. Windows XP feels a little better, and PowerShell is another animal altogether. With the latter pair, you do get file or folder autocompletion upon hitting the TAB key. What I didn't realise until recently was that continued tabbed cycled through the possibilities; I was hitting it once and retyping when I got the wrong folder or file. I stand corrected. With the shell in Linux/UNIX, you can get a listing of possibilities when you hit TAB for the second time and the first time only gives you completion as far as it can go with certainty; you'll never get to the wrong place, though you may not get anywhere at all. This works for bash, but not ksh88 as far as I can see. It's interesting how you can take two different approaches to reach the same end.
Numeric for loops in Korn shell scripting: from ksh88 to ksh93
18th October 2007The time-honoured syntax for a for
loop in a UNIX script is what you see below, and that is what works with the default shell in Sun's Solaris UNIX operating system, ksh88.
for i in 1 2 3 4 5 6 7 8 9 10
do
if [[ -d dir$i ]]
then
:
else
mkdir dir$i
fi
done
However, there is a much nicer syntax supported since the advent of ksh93. It follows C language conventions found in all sorts of places like Java, Perl, PHP and so on. Here is an example:
for (( i=1; i<11; i++ ))
do
if [[ -d dir$i ]]
then
:
else
mkdir dir$i
fi
done
Detecting file ownership in Korn shell scripts
17th October 2007I recently was having a play with using a shell script to do some folder creation to help me set up a system for testing, and I started to hit ownership issues that caused some shell script errors. At the time, I didn't realise that there is a test that you can perform for ownership. The "-o" in the code below kicks in the test condition and avoids the error in question.
if [[ -o $dirname ]]
then
cd test
for i in 1 2 3 4 5 6 7 8 9 10
do
if [[ -d study$i ]]
then
:
else
mkdir study$i
fi
done
ls
cd ~
fi
Previously, I shared a way to test for directory (-d operator) and file (-f operator) existence that follows the above coding convention. However, there are a plethora of others and I have made a list of them here:
Operator | Condition |
-e file |
File exists |
-L file |
File is a symbolic link |
-r file |
User has read access to file |
-s file |
File is non-empty |
-w file |
User has write access to file |
-x file |
User has execute-access to file |
-G file |
User's effective group ID is the same as that of the file |
file1 -nt file2 |
File 1 is newer than file2 |
file1 -ot file2 |
File 1 is older than file2 |
file1 -et file2 |
File 1 was created at the same time as file2 |
It's all useful stuff when you want to rid the command line output of errors in an above board way. These are the kinds of things that often make life easier...
Negative logic in Korn shell scripts
16th October 2007I was looking for a way to negative logic, doing something when a condition is not satisfied, that is, and found that the way to do it is to do nothing when the condition is satisfied and something when it isn't. Being used to saying do something when a condition is false, this does come as a surprise. In time, I may find another way on my UNIX shell scripting journey. Meanwhile, the code below will only create a directory when it doesn't already exist.
dirname=test
if [[ -d $dirname ]]
then
: # the colon operator means do nothing
else
mkdir test
fi
The power of pipes
12th July 2007One of the great features of the UNIX shell is that you can send the output from one command to another for further processing. Take the following example for instance:
ls -l | grep "Jul 12"
This takes the long directory file listing output and sends it to grep
for subsetting (all files created today in this example) before it is returned to the screen. The |
character is the pipe trigger, and you can have as many pipes in your command as you want, though readability may dictate how far you want to go.
Using Korn shell commands in scripts running under the bash shell
19th May 2007This is actually a fairly simple one: just prefix the relevant command with ksh
like below (in the example below, bash
won't know what to do with the print command otherwise):
ksh print "Hello, world!"
It's also useful for running Korn shell scripts under the bash shell as well.
Recalling previous commands in the Korn shell
18th May 2007The default shell on Solaris boxes seems to be Korn and the version that I have encountered doesn't appear to allow obvious access to the command history. In the bash shell, the up and down cursor keys scroll through your command history for you, but Korn doesn't seem to allow this. Thankfully, there is another way: you can set up the editor vi as the default method for gaining access to the command history by adding the following line to the .profile
file in your home directory:
set -o vi
Then, you can use the Vi (it's pronounced vee-eye, apparently) commands ESC+h
and ESC+j
to move up and down the list of previous commands. That, or, assuming that you have access to it, just use the bash shell anyway...