Click here to Skip to main content
15,883,883 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am trying to access a variable outside of function but I cant get it to work properly it might have something to do with the subshell but I am not too sure. I'm very new to shell at the moment

I am trying to access the elapsed variable from this function and use it in my case statement I provided in the code below. I keep getting the wrong output of -3 in my time column and the error "line 20: [: -lt: unary operator expected"
Any help would be appreciated than you


Shell
#! /bin/bash


number=$1

if [ "$1"  -le 1 ] ;

then
        echo -e "Number can not be negative or equal to 1, pleaes enter a new number.\n";
        exit
fi;

recur_fib()
{
  first_num=$1

  #start time
  START=$(date +%s%6N);

  [ $first_num -lt 2 ]  && echo -n $first_num || echo -n $(( $( recur_fib $(( first_num - 1 )) ) + $( recur_fib $(( first_num - 2 )) ) ))

  #end time
  END=$(date +%s%6N)

 let  elapsed=$END-$START | bc

}

totaltime=$(recur_fib $elapsed)
#recursive
val_recur=$(recur_fib $1)

#nonrecursive

nonrecur_fib()
{
  first_num=$1
  first_fib=0
  second_fib=1

  #start time
  start_time=$(date +%s%N)

  #loop for nonrecur
  for ((number=0; number<=first_num; number++))
    do
        echo -n "$first_fib "
        total=$((first_fib+second_fib))
        first_fib=$second_fib
        second_fib=$total
    done
  #end time
  end_time=$(date +%s.%6N)
  let nonrecur_time=$end_time - $start_time 
}

#without recursion
val_without=$(nonrecur_fib $1)

total_nonrecur_time=$(nonrecur_fib $nonrecur_time)

  #date and time
  echo START: `date +"%m-%d-%Y %H:%M.%S.%N"` | tee -a fibonacci.out

  #allowing user to enter R or r and N or n to chose the method
  echo "Please enter the method you would like to use to calculate the sequence Non-recursive(N) or Recursive(R)"
  read method

  #telling the user the calculations will start
  echo -e "The calculations will start now"

case $method in
#case for nonrecursive
        "N" | "n")
                echo -e "NON-RECURSIVE $1\n" | tee -a fibonacci.out

                echo -e "Run\tFibonacci\t\t\tTime" | tee -a fibonacci.out

                 count=1
                while [ $count -le $1 ]
                do
                        echo -e "$count" '\t' $val_without '\t''\t''\t' $total_nonrecur_time | tee -a fibonacci.out
                        ((count = count + 1))

                done

                echo Average Time: $(((count * total_time1) / count))
                echo END: `date +"%m-%d-%Y %H:%M.%S.%N"` | tee -a fibonacci.out
                echo Total time: $((count * total_nonrecur_time)) | tee -a fibonacci.out
                echo "Run is done" | tee -a fibonacci.out

                ;;
#case for recursive
        "R" | "r")
                #repeat the the method and number chosen
                echo -e "RECURSIVE $1\n" | tee -a fibonacci.out

                echo -e "Run\tFibonacci\tTime" | tee -a fibonacci.out

                count=1
                while [ $count -le $1 ]
                do
                        echo -e "$count" '\t' $val_recur '\t''\t' $totaltime | tee -a fibonacci.out
                        ((count = count + 1))

                done

                #shows average time
                echo Average Time: $(((count * totaltime) / count)) | tee -a fibonacci.out
                #shows end time
                echo END: `date +"%m-%d-%Y %H:%M.%S.%N"` | tee -a fibonacci.out
                #shoes total time
                echo Total time: $((count * totaltime)) | tee -a fibonacci.out
                echo "Run is done" | tee -a fibonacci.out
                ;;
        *)
                echo "Please chose either R,r or N,n"


What I have tried:

Some of the stuff I was reading was to try the export command that didn't work. I tried to mess around with changing some of the position's of ")" but nothing worked
Posted
Updated 12-May-22 6:37am
v3
Comments
Richard MacCutchan 12-May-22 4:00am    
It is not clear which of these blocks of code you are running, what inputs you are feeding them, or where line 20 is.
Bryan Woodruff 12-May-22 8:49am    
Hello Richard,
Sorry for not being more specific on my question, I am trying to access the elapsed variable inside the recur_fib() function so I can get the time it takes for the function to calculate. When I try to access it how I have it now "total_time=$(recur_fib $elapsed)" it gives me -3. Which can't be right since it I am looking for the time it took to complete which should be positive.

As to the line 20 error, line 20 is "[ $first_num -lt 2 ] && echo -n $first_num || echo -n $(( $( recur_fib $(( first_num - 1 )) ) + $( recur_fib $(( first_num - 2 )) ) ))"

Hopefully you can give some assistance to where I am going wrong. I also tried the export command inside the function but that didn't work.
Richard MacCutchan 12-May-22 9:14am    
Sorry, I am still confused. I cannot see the connection between the two code snippets, or how the line you refer to can be line number 20 (is's line 8 in my test). I have copied both scripts but neither of them will run as posted. Where are you running these scripts and how are they connected? And also importantly what (if any) inputs are you feeding to them?
Bryan Woodruff 12-May-22 10:22am    
Hey Richard I updated the code to what I have wrote in all. Sorry I dont normally post on here I usually try to figure it out myself. Also I am feeding it a command line input called ./lab10.sh 10
Richard MacCutchan 12-May-22 11:03am    
There are still too many errors in the script even to get it to run, so it is difficult even to guess why the results are as printed. I suggest you forget this and start a new script which just contains the code to do the non-recursive calculation with a hard coded start value. Once you have that working correctly you can go on to the recursive version. Once you have both functions working you can then move on to the time calculations, and the other enhancements.

I'm assuming your using bash. First off, I assume that the line elapsed=$(( end-time - start_time )) is just a typo and that end-time should be end_time
But looking at that statement, it's all just wrong. If you are using bash, then you could use a let expression to evaluate the elapsed time:
Bash
let elpased=$end_time-$start_time
If you're not using bash, and are using some other POSIX type shell that does not support the let syntax, you can always use expr
Shell
elapsed=$(expr $end_time - $start_time)
 
Share this answer
 
Comments
Bryan Woodruff 12-May-22 10:24am    
Hello I appreciate your time in trying to help me solve my problem. I changed my code to try "let" this time. I am still getting -3 for my the time it took to run the program. Also I am using bash. I might be explaining my problem badly, I dont normally post on here I usually try to figure it out myself.
k5054 12-May-22 11:04am    
when using let, do not add spaces to the the statement. Use let var=a$-$b not let var=$a - $b
k5054 12-May-22 11:14am    
Ah. Ok, so you're trying to do floating point math, whereas the shell only supports integer math. What you'll need to do is to use something like perl to do this, eg elapsed=$(perl -e "print $end_time - $start_time")
Here is a simple recursive function to print the Fibonacci sequence up to 100:
Shell
fibo()
{
    echo -n $1
    if [ $2 -lt 100 ]; then
        echo -n ", "
        let tot=$1+$2
        fibo $2 $tot
    fi
    echo ""
}

fibo 0 1

It should be fairly easy to adapt that to your requirements, and to create a non-recursive version.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900