Results 1 to 5 of 5
Hi, all.
I have a script that can take multiple arguments. The arguments are either integers or characters such as "jsousa". Here's the usage where [] means optional:
Code:
script_name ...
- 10-13-2008 #1Just Joined!
- Join Date
- Oct 2008
- Posts
- 11
functions and for loops
Hi, all.
I have a script that can take multiple arguments. The arguments are either integers or characters such as "jsousa". Here's the usage where [] means optional:
Actually, the first argument can be either an integer or a string. In my script, I have a function called, is_num() that checks if an argument is an integer. The function works so I'm not worried about that. But the code I wrote that uses the function doesn't. First, here's a simplified version of my code that DOES work. It says:Code:script_name 12345 [98765] [jsousa] [bross]
If the argument is a number, then print PASS
If the argument is not a number, then print FAIL
Code:for arg; do if is_num $arg; then print "PASS: " $arg else print "FAIL: " $arg fi done
This input:
Produces this output:Code:script_name 12345 jsousa
Code:PASS: 12345 FAIL: jsousa
All is well. But when i expand my PASS section and insert a for loop, I get very different results. I was expecting that only the arguments that pass the is_num function would run through my inner for loop. But ALL of my arguments are running through it. I don't understand why.
Code:for arg; do if is_num $arg; then for arg; do print "PASS: " $arg done else print "FAIL: " $arg fi done
Now this input:
Produces this output:Code:script_name 12345 jsousa
Code:PASS: 12345 PASS: jsousa FAIL: jsousa
Why is "jsousa" passing? Why is it getting past is_num()?
Thanks for your help and let me know if I am not being clear.
- 10-14-2008 #2
So this is related to the syntax of a Bash for loop. The formal syntax is:
If the list is omitted, then by default it will loop through the arguments to the script.Code:for <var> [in <list>]; do <body>; done
So let's see what happens:
So we start with the outer loop, looping through each argument to the script. The first argument is 98765. Is it a number? Yes. In that case, we loop through each argument to the script, printing "PASS: $arg" for each one. So we print "PASS: 98765", then "PASS: jsousa".
Now we go back to the outer loop. Now we're on the second argument: "jsousa". Is it a number? No. So we print "FAIL: jsousa".
Does this make sense?
My immediate question is why do you have this inner for loop? What is it supposed to do? Shouldn't you only be passing the one variable that passed? I don't understand the loop.
Hope that helps.DISTRO=Arch
Registered Linux User #388732
- 10-14-2008 #3Just Joined!
- Join Date
- Jul 2008
- Posts
- 73
I agree with the previous poster, except I am of the opinion that you should move the if statement inside the loop, looping through the arguments then would produce the results you are looking for.
Later, Ray Parrish
Never mind, just saw the outer loop, yes I agree the inner loop is redundant and is causing the problem.
- 10-15-2008 #4Just Joined!
- Join Date
- Oct 2008
- Posts
- 11
Hi, again.
Thanks so much for all of your repsonses. They really help. The reason I use an inner for loop is that 1) I thought that the outer one would filter out all non-numbers, and 2) I need to verify that the numbers themselves match nummbers in a file called, master_file. Here's my real code:
Code:is_num() { (( $# == 0 ))&&print "Usage: is_num number" && exit 1 a=$(echo "$1" | grep "^[0-9]\{5\}$") [ -n "$a" ] && return 0 || return 1 } for arg; do if is_num $arg; then for num; do a=$(grep "^x$num:" master_file) [ -z "$a" ] && print "WARNING:" $num "is not in mastet_file" && continue f2=$(echo $a | cut -d: -f2) if [ -z "$f2" ]; then print "WARNING:" $num "does not have any users in master_file." else print $f2 | tr ',' '\n' >> list_users continue fi done else echo $arg >> list_users fi done
Is there a way around this dilemna? Can I do something else to ensure that only numbers enter the inner loop?
Thanks.
- 10-18-2008 #5
Interesting, and good to know the context, but I still don't understand why you would need the inner loop.
Each iteration of the outer loop is for one argument. If you just put the conditional directly into this loop, it will be applied to one argument at a time, and action taken if it's a number. The inner loop isn't looping over anything, so there's no need to have a loop.DISTRO=Arch
Registered Linux User #388732


Reply With Quote