Help with simple script with counter

Use and complete the template provided. The entire template must be completed. If you don't, your post may be deleted!

  1. The problem statement, all variables and given/known data:

I am to create a script that checks a file for specific attributes. Read, write, execute, if the file is empty, and if the sticky bit is set. I have completed this step but I am stumped on how to add a simple counter and to have the script repeat the process of identifying access rights as many times as the person running the script wants. I am to prompt the user to enter another file name or an X to exit the script.

  1. Relevant commands, code, scripts, algorithms:

  2. The attempts at a solution (include all code and scripts):

     1
     2  count = 1
     3  echo -n "Please enter a filename: "
     4  read filename
     5  while ["$1" != "$filename"]
     6  do
     7   echo "Invalid filename..."
     8   read filename
     9  done
    10  if [ -d "$1" ]
    11    then
    12    echo "The diretory $1 exists."
    13  else
    14    echo "The directory $1 does not exist."
    15  fi
    16   if [ -e "$1" ]
    17    then
    18  echo "The file $1 exists and has the following properties: "
    19  fi
    20   if [ -r "$1" ]
    21    then
    22    echo -n "Read. "
    23   fi
    24   if [ -w "$1" ]
    25   then
    26   echo -n "Write. "
    27  fi
    28   if [ -x "$1" ]
    29   then
    30   echo "Execute."
    31  fi
    32  if [ -k "$1" ]
    33   then
    34   echo "Sticky bit is set."
    35   else
    36   echo "Sticky bit is not set."
    37  fi
    38  if [ -s "$1" ]
    39   then
    40   echo "The file is not empty."
    41   else
    42   echo "The file is empty."
    43
    44  count=`expr $count+1`
    45  fi
    46  echo "Your total count is"
    47  echo "$count"

any help would be greatly appreciated as I am completely stumped. If i remove the count syntax's, it prompts me to enter a filename but displays an error for line 5.

  1. Complete Name of School (University), City (State), Country, Name of Professor, and Course Number (Link to Course)
    Westchester Community College, NY, United States, Cordino, COMSC118

There should be spaces after `[' and before `]' like so:

while [ "$1" != "$filename" ]

As opposed to variable assignments where there should be no spaces around the assignment operator (hint). Also have a look at what the meaning of $1 is. It is often used to pass parameters (command line values) to a script, so the while loop does not seem to make much sense here and also the read statement needs to put its outcome somewhere in a variable, plus the count variable is not incremented inside a loop.

It is not unusual to forget about good coding practices when writing scripts. This is wrong. You already have a script which checks for one file one time. Why don't you put what you have into a function (read about shell functions in the man page of your shell) and call that function?

If you have a command, say: "foocommand", and want to execute it a 100 times, this usually looks like (pseudocode)

while counter lower than 100
     foocommand
     counter ++
end while

Wouldn't it be easier to write something like this in shell code, instead of cramming all the functionality into one big loop? Incidentally it would also bring a solution to your other problem once you figure out how to pass parameters to a function.

Anopther thing:

count=`expr $count+1`

This is neither wrong nor illegal, but you should avoid that anyway. Backticks are outdated and deprecated and generally not considered good style. Furthermore, in modern shells you do not need "expr" because any shell has a built-in way to handle integer operations. This:

(( count += 1 ))

Does the same in ksh and bash and is easier to read too. If you need process substitution (in this case you don't) you wouldn't use backticks either but:

var=$(/some/command | /other/command | .... )

I hope this helps.

bakunin

is Bourne shell, works in any shell.
If there is a Posix/standard shell (or ksh or bash or zsh) the following is recommended because it avoids the external program expr

count=$(( count+1 ))

While

only works in ksh93 and bash and zsh, and has no further speed enhancement.

1 Like

Staying POSIX, one can even use:

i=0
while [ $((i+=1)) -le 100 ]
1 Like

Hmm, interesting. Consequently the following is Posix, too:

: $(( count+=1 ))

So ((count++)) is not suggested?
Or is that as well just bash,ksh93 and zsh?

Unfortunately yes.

1 Like

it is Bourne shell, yes, and will work in any shell compatible with the Bourne shell, yes, but will not work in shells not compatible with the Bourne shell.

Generally, backwards compatibility with the Bourne shell is of course a valuable asset nowadays. But wouldn't it be better to go the whole distance? The Bourne-shell was built as an extension to the Thompson-shell (osh) in which the backticks won't work either. To avoid backwards compatibility problems with systems lacking a Bourne-shell and having only a Thompson-shell (like, for instance, most pre-SysV-systems as well as perhaps all the Multics systems) maybe a completely different approach would be best?

Actually it works in any ksh, not only ksh93. In fact this is exactly what i said:

I still have to see a "POSIX shell" which is not either a "POSIX-compatible ksh" or a "POSIX-compatible bash", therefore i think that the POSIX-issue is moot in this case.

I hope this helps.

bakunin

A pregnant lady goes to the clinic all concerned. In the process of addressing her concerns, a doctor discovers something abnormal in the unborn.

Another doctor knocks the door opening it ajar.

"Come on in, Doctor!" Let me show you the umbilical hernia that this baby has.
"Sorry, Doctor!" This looks to me more like a gastroschisis.

"Knock, knock!" - Another doctor interrupts at the now open door.

"Doctor! Come in! Take a look at this umbilical hernia"
"That's an exomphalos!" - Authoritatively, this latest doctor declares - "Poor 'bugger' is going to require surgery"

Is the thread starting to sound as such? - I ask myself.
Yes! Too many doctors.

No offense guys. Just an observation.

Bakunin, you are right, (( count+=1 )) works in older ksh, too. (But not (( count++ )) .)
Maybe I tested with another Posix shell: posh, dash, ...

Thanks for the input. I am not sure the other suggested shell scripts work in my bash shell, and the professor wants it a specific way. My script now looks like this.

     1  count=1
     2  if [ -d "$1" ]
     3    then
     4    echo "The diretory $1 exists."
     5  else
     6    echo "The directory $1 does not exist."
     7  fi
     8   if [ -e "$1" ]
     9    then
    10  echo "The file $1 exists and has the following properties: "
    11  fi
    12  echo "Please enter another filename or an x to exit the script: "
    13  while [ "$filename" != "x" ]
    14  do
    15  read filename
    16   if [ -r "$1" ]
    17    then
    18    echo -n "Read. "
    19   fi
    20   if [ -w "$1" ]
    21   then
    22   echo -n "Write. "
    23  fi
    24   if [ -x "$1" ]
    25   then
    26   echo -n "Execute."
    27  fi
    28  echo " "
    29  if [ -k "$1" ]
    30   then
    31   echo "Sticky bit is set."
    32   else
    33   echo "Sticky bit is not set."
    34  fi
    35  if [ -s "$1" ]
    36   then
    37   echo "The file is not empty."
    38   else
    39   echo "The file is empty."
    40  fi
    41  COUNTER=`expr $COUNTER + 1`
    42  echo "Please enter a filename or an x to exit the script: "
    43  read filename
    44  done
    45  echo "$COUNTER"

The problem is no matter what file I test it against it doesn't seem to be reading "$1". It only outputs

Read. Write.
Sticky bit is not set.
The file is not empty.
Please enter another filename or an x to exit the script:

. Even when I press x to exit, it will output the above and then exit. The counter still doesn't seem to be working properly. Thanks in advance

$1 is the parameter with what you run the script e.g.

./myscript thisfile

and $1 becomes thisfile.
Your read goes to variable filename. You get its value by $filename