[EMAIL PROTECTED] wrote:
Hey All!

Hello,

I've written a Bash script called `clock`, which is called by one of
two symbolic links: `clock-in` and `clock-out`.  This script is,
effectively, a time-clock for tracking time spent on various projects
for clients.  This script generates a "time card" file, if one does
not exist in my "$HOME/Timecards" folder, and/or appends to the "time
card' file.  The file name is the first parameter passed into my
`clock` script.  The second parameter is a note to be placed with
either the clock-in or clock-out to give a little detail to the "time
card".

Now, I'm trying to write a Perl script that will open a "time card"
and process it to generate an invoice based on the information in the
"time card" file.  However, whenever I try to open any of the time
card files in my Timecards folder, I get the error "Inappropriate
ioctl for device".  I've read other posts in this group, as well as
many others, but have not found a solution to this error.  I am
pasting the code below for your review, to see if I've made some kind
of odd mistake with the Perl syntax.  I've got a lot of programming
experience, but not much with Perl, so I'm just applying my knowledge
of other languages to Perl and trying to learn the syntax as I go.
Please forgive any conventions that I may have used that aren't common
to Perl.  Here's the code in question:

######################################################################
# Create a variable to hold the path to the TimeCard files.  These   #
# should be located in a folder, under the user's home folder, called#
# 'Timecards'.                                                       #
######################################################################
$TimeCardsPath = $ENV{'HOME'} . "/Timecards/";

#######################################################################
# Check for command-line arguments.  If there are none, call exit()
#
# with the command-line usage error as a parameter.
#
#######################################################################
if ( !defined( $ARGV[0] ) ) {

That is usually written as:

if ( @ARGV != 1 ) {


        $ExitStatus = $EX_USAGE;
        ExitScript();

Why not pass $EX_USAGE to ExitScript() instead of using global $ExitStatus?

        ExitScript( $EX_USAGE );


} else {
        # Let the user know that we are processing the filename that they
passed
        # in to the script.  Also, this shows the user that we are processing
        # TimeCards from a specific directory in their $HOME folder,
according
        # to the Bash Environment Variable.
        print "Processing:  $TimeCardsPath$ARGV[0]\n";

        # Declare a variable to hole each line of the TimeCard file.
        $Line = "";

        # Declare four variables to hold the introductory note, time in, time
out
        # and closing note of the clock punch.
        $iNote = "";
        $TimeIn = "";
        $TimeOut = "";
        $cNote = "";

        # Now, we need to create a file handle to access the TimeCard file.
        open ( TIMECARD, $TimeCardsPath . $ARGV[0] ) ||
                die $ExitStatus = $EX_NOINPUT;

die() exits the program.


        # Check to see if we were able to open the TimeCard file:
        if ( $ExitStatus = $EX_NOINPUT ) {

You are using the assignment operator so the test is always true. You need to test for numerical equality instead:

        if ( $ExitStatus == $EX_NOINPUT ) {


                # We need to let the user know that we were unable to open
                # the TimeCard and exit the script.
                print "Unable to open the file:\n";
                print "\t$TimeCardsPath$ARGV[0]\n";
                print "Please make sure that the file exists in the above 
path\n";
                print "and that you have read access to the file.\n";
                print "\nReturned Error:\n\t";
                print "$!\n\n";

You are using the $! variable six statements away from the open() statement which means that there is no guarantee that its value will be related to what open() may have set it to.


                ExitScript();
        } else {  # Process the file and create the invoice.
                # Implement processing here.


                # Close the input file.
                close ( TIMECARD );
                # Exit the script with normal termination status.
                exit ( $EX_OK );
        } # End of invoice generation.
} # End of command-line parameter check.

sub ExitScript {

Pass the exit code to your subroutine:

        my $ExitStatus = shift;


        if ( $ExitStatus == 64 ) {

Shouldn't that be:

        if ( $ExitStatus == $EX_USAGE ) {


                system ( 'clear' );
                print "INVOICE GENERATOR v0.6\n";
                print "~~~~~~~~~~~~~~~~~~~~~~\n";
                print "PekinSOFT Systems\n";
                print "Copyright(c) 2008\n";
                print "\n";
                print "\n";
                print "USAGE:  invoice {TimeCard Filename}\n";
                print "\n";
                print "   TimeCard Filename\tName of the time card for which to 
have
an invoice generated.\n";
                print "\n";

The subroutine is named 'ExitScript' but you are not exiting here?


        } else {
                exit( $ExitStatus );
        } # End of ExitStatus check.
} # End of ExitScript() function.

This code includes everything except my opening comments describing
the script and the definition of my exit status codes, which are taken
directly from `sysexits.h`.  In my `die` statement, I'm setting the
ExitStatus variable, which is not something that I see in examples of
the `open` statement...I only see something like:  `die "Error
message"`, so I don't know if that's causing the problem or even if
that is a legal statement.

Here is the output that I'm getting when I run the script:

Processing:  /home/sean/Timecards/TimeCards
Unable to open the file:
        /home/sean/Timecards/TimeCards
Please make sure that the file exists in the above path
and that you have read access to the file.

Returned Error:
        Inappropriate ioctl for device

As you can see in the output, the path is displaying correctly, so I
assume that the path is also correct in the `open` statement.
However, in the `open` statement, I am using the concatenation
operator (.) instead of doing like it is in my `print` statements.
Could this be causing the problem?

Steps that I've taken:
1)  Checked to make sure that I have no typos in my path and I don't.
2)  Checked to make sure that the file exists and it does.
3)  Checked to make sure that I have read access to the file and the
Timecards folder, which I do because I
      created the folder and the file through my Bash script.
4)  Made sure that I have no errors on my file system and I don't.


John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order.                            -- Larry Wall

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/


Reply via email to