Read command not working as expected

I was trying to write a simple script which will read a text file and count the number of vowels in the file. My code is given below -

#!/bin/bash
file=$1
v=0

if [ $# -ne 1 ]
  then
    echo "$0 filename"
    exit 1
fi

if [ ! -f $file ]
  then
    echo "$file not a file"
    exit 2
fi

while read -n 1 c
do
  l=$(echo $c | tr [:upper:] [:lower:])
  [[ "$l" == "a" || "$l" == "e" || "$l" == "i" || "$l" == "o" || "$l" == "u" ]] && (( v++ ))
done < $file

echo "Vowels : $v"

When I run the script, getting the following error -
read: 22: Illegal option -n
However the command read -n 1 c is working fine if I run it from terminal.
Any suggestion is appreciated.
Thanks in advance.

I cut and pasted your code and it works fine for me (reading with -n 1). Is it possible that the version of bash that is being invoked isn't the same one executed as your login shell?

You could try something like this that doesn't depend on reading character by character:

while read buf
do
    vbuf="${buf//[^aeiouAEIOU]/}"
    v=$(( v + ${#vbuf} ))
done <$file
echo "$v vowels"

This works in both bash and Kshell.

1 Like

A similar method - use "tr" to delete everything except the vowels and count the result.

file="$1"
vowels=$(fold -w 1 "${file}" | tr -cd 'aeiouAEIOU' | wc -c)
echo "Vowels : ${vowels}"

Can try this too...

# egrep -io "a|e|i|o|u"  $1 | wc -w

eg.

[root@nagios Shirish@Shukla]# cat my
aa b c d e f g h i j k l m n o p q r s t u v w x y z
[root@nagios Shirish@Shukla]# cat test.sh
echo "Vovels: "`egrep -io "a|e|i|o|u" $1 | wc -w`
[root@nagios Shirish@Shukla]# sh test.sh my
Vovels: 6

--Shirish Shukla

1 Like

I don't see the need for fold since the complemented tr set will delete non-vowels anyway (including newlines). Also, it looks like your finger slipped off the capslock. :wink:

tr -cd aeiouAEIOU < "$file" | wc -c

Regards,
Alister

2 Likes

Thanks everyone for your suggestion. But my focus was to run the script, not the algorithm to count the vowels. Sorry for misguiding you.
My problem is that whenever I am trying to run any script from terminal, getting unusual errors like no such commands or invalid option with the command or syntax error etc. But the same commands are working from the terminal separately.
Do I need any settings to run the script? In the script, I am using bash shell, and the same for terminal. If anyone has any suggestion, please let me know.
Thanks in advance.

Just on the off chance, it's not the same problem as before is it?
http://www.unix.com/shell-programming-scripting/177690-running-shell-script-cygwin-terminal.html

Please post the output from this command which is designed to make control characters visible:

sed -n l scripname

A normal end-of-line character shows as a dollar sign.

1 Like

Methyl, it is not the same problem as the previous one.
In the previous case, the script was executed from cygwin terminal in win xp environment. But now I was trying to run the script from linux terminal in Ubuntu env.
I guess the problem might be due to some shell related or setting problem. As I am new to linux, can't figure out the exact problem.
I will post the output of the command once I execute the command in my ubuntu laptop. Thank you.

How are you calling the script? If you call it for example as sh ./script then the shebang is ignored and you are using /bin/sh , which is dash on Ubuntu, not bash....

I was calling the script as sh scriptname

Right, then that explains it. So you would need to use ./scriptname or bash ./scriptname..

1 Like

@linux_learner
When posting a problem please state what Operating System and version you are running and what Shell you are using. Every time.
When you have a problem please post the script intact (blotting anything confidential with X's) and any error messages verbatim.
If there is a question about different environments please post the output from the command set for both the environment which works and the environment which does not work. Just doing this will often make the solution obvious to you. Sometimes a cron containing just set will reveal the problem.

Back on topic.
Srutinizer has cracked it. You ran a "bash" Shell in a "dash" environment. This was unguessable based on the information originally posted.
Now if you had posted the exact error messages verbatim?

The main lesson here is that "bash" has many extensions to scripting language which are really useful but which do not work at all in normal unix Shells.

When you get an error message, post the error message 100% accurately case-significant and with every space character intact.
There is no Shell which outputs "no such commands" or "invalid option with the command" but there are some which output "syntax error" but probably not in lower-case.

1 Like

Thanks methyl and Scrutinizer, now it is clear to me and it is working as expected.

@Scrutinizer, could you please explain me how to check which shell is being used when I am running some script in Ubuntu? If I run the command echo $SHELL, it displays /bin/bash, so I thought the script was run in bash shell.

Thanks in advance.

Hi linux_learner, sh script means that /bin/sh will be used to execute the script, overriding any shell that is specified on the first line in the script that starts with #!
Historically /bin/sh was the Bourne Shell, on modern systems /bin/sh usually means a POSIX shell, with a limited set of features of what bash offers. So if you use sh, you should limit yourself to the POSIX feature set. On many linuxen /bin/sh this is a link to /bin/bash and if bash gets called this way it conforms to POSIX more closely, but not fully ( for example read -n still works ). On Ubuntu /bin/sh is linked to /bin/dash, which is a very fast shell that is pretty near a POSIX shell and not much else..

1 Like

Thanks Scrutinizer, now it is clear to me.