Discussions
Categories
- 17.9K All Categories
- 3.4K Industry Applications
- 3.4K Intelligent Advisor
- 75 Insurance
- 537.7K On-Premises Infrastructure
- 138.7K Analytics Software
- 38.6K Application Development Software
- 6.1K Cloud Platform
- 109.6K Database Software
- 17.6K Enterprise Manager
- 8.8K Hardware
- 71.3K Infrastructure Software
- 105.4K Integration
- 41.6K Security Software
Why a recursive script has trouble calling itself?

Hi,
I have this simple rescursive script.
#!/bin/ksh#PS4='+$(date "+%F %T") ${FUNCNAME[0]}() $BASH_SOURCE:${BASH_LINENO[0]}+ 'set -o xtrace # Comment this line to disable tracing.if [ -z $count ] then count=0fithis_dir=`pwd`if [ $count < 10 ] then ((count++)) echo 'count '$count ${this_dir}/$0 fiecho "Out of it!"exit 0
As you can see I'm having it traced in the commands up-top.
I'm getting the following traced output:
[email protected] $ ./reroute.ksh +2018-04-26 09:47:26 () :+ [ -z ]+2018-04-26 09:47:26 () :+ count=0+2018-04-26 09:47:26 () :+ pwd+2018-04-26 09:47:26 () :+ this_dir=/home/c037024+2018-04-26 09:47:26 () :+ [ 0 ]+2018-04-26 09:47:26 () :+ ./reroute.ksh[13]: 10: cannot open [No such file or directory]+2018-04-26 09:47:26 () :+ echo 'Out of it!'Out of it!+2018-04-26 09:47:26 () :+ exit [email protected] $
Why does it not recognize the script I'm trying to call?
Best Answer
-
If you you execute ./reroute.ksh then $0 will be ./reroute.ksh
this_dir=/home/c037024 and ${this_dir}/$0 will essentially execute the following:
/home/c037024/./reroute.ksh
That of course won't work.
However, the logic of your procedure is bad. The way I see it, you are creating an infinite loop. Not only will executing the program again not know about "count", but you are also continuously resetting it to 0. Making a program call itself will still load the stack with whatever remains in the initial procedure. Making a program call itself is always a bad idea. I suggest you create a function, rather than having the program call itself.
Answers
-
Hi.
Change line 13 if [ $count < 10 ] to
if (( $count < 10 ))
or
if [ $count -lt 10 ]
Also you must export variable count. Or you got fork bomb.
Change count=0 to
export count=0
Regards,
Nik
-
If you you execute ./reroute.ksh then $0 will be ./reroute.ksh
this_dir=/home/c037024 and ${this_dir}/$0 will essentially execute the following:
/home/c037024/./reroute.ksh
That of course won't work.
However, the logic of your procedure is bad. The way I see it, you are creating an infinite loop. Not only will executing the program again not know about "count", but you are also continuously resetting it to 0. Making a program call itself will still load the stack with whatever remains in the initial procedure. Making a program call itself is always a bad idea. I suggest you create a function, rather than having the program call itself.
-
Why ksh? Ksh under Linux is not the same as good old ksh on Unix systems. Pdksh is no longer available, at least not for current OS distributions. I could not think of any good reason to use ksh over bash. Linux uses bash. You are increasing the odds using ksh and Linux admins may not be able to help you with ksh specifics.
-
Yup! There it is! I was literally board at work this morning so I started playing with recursion. This simple script illustrates it pretty well for the unindoctrinated from beggining to end.
First, the corrected script.
[email protected] $ cat reroute.ksh#!/bin/ksh#PS4='+$(date "+%F %T") ${FUNCNAME[0]}() $BASH_SOURCE:${BASH_LINENO[0]}+ 'set -o xtrace # Comment this line to disable tracing. if [ -z $count ] then export count=0fi if [ $count -lt 10 ] then ((count++)) echo "count "$count ./$0 fiecho "Out of it!"echo "count back! "$countexit 0
And, of course, the output.
[email protected] $ ./reroute.ksh +2018-04-26 13:36:02 () :+ [ -z ]+2018-04-26 13:36:02 () :+ count=0+2018-04-26 13:36:02 () :+ export count+2018-04-26 13:36:02 () :+ [ 0 -lt 10 ]+2018-04-26 13:36:02 () :+ ((count++))+2018-04-26 13:36:02 () :+ echo 'count 1'count 1+2018-04-26 13:36:02 () :+ ././reroute.ksh+2018-04-26 13:36:02 () :+ [ -z 1 ]+2018-04-26 13:36:02 () :+ [ 1 -lt 10 ]+2018-04-26 13:36:02 () :+ ((count++))+2018-04-26 13:36:02 () :+ echo 'count 2'count 2+2018-04-26 13:36:02 () :+ ./././reroute.ksh+2018-04-26 13:36:02 () :+ [ -z 2 ]+2018-04-26 13:36:02 () :+ [ 2 -lt 10 ]+2018-04-26 13:36:02 () :+ ((count++))+2018-04-26 13:36:02 () :+ echo 'count 3'count 3+2018-04-26 13:36:02 () :+ ././././reroute.ksh+2018-04-26 13:36:02 () :+ [ -z 3 ]+2018-04-26 13:36:02 () :+ [ 3 -lt 10 ]+2018-04-26 13:36:02 () :+ ((count++))+2018-04-26 13:36:02 () :+ echo 'count 4'count 4+2018-04-26 13:36:02 () :+ ./././././reroute.ksh+2018-04-26 13:36:02 () :+ [ -z 4 ]+2018-04-26 13:36:02 () :+ [ 4 -lt 10 ]+2018-04-26 13:36:02 () :+ ((count++))+2018-04-26 13:36:02 () :+ echo 'count 5'count 5+2018-04-26 13:36:02 () :+ ././././././reroute.ksh+2018-04-26 13:36:02 () :+ [ -z 5 ]+2018-04-26 13:36:02 () :+ [ 5 -lt 10 ]+2018-04-26 13:36:02 () :+ ((count++))+2018-04-26 13:36:02 () :+ echo 'count 6'count 6+2018-04-26 13:36:02 () :+ ./././././././reroute.ksh+2018-04-26 13:36:02 () :+ [ -z 6 ]+2018-04-26 13:36:02 () :+ [ 6 -lt 10 ]+2018-04-26 13:36:02 () :+ ((count++))+2018-04-26 13:36:02 () :+ echo 'count 7'count 7+2018-04-26 13:36:02 () :+ ././././././././reroute.ksh+2018-04-26 13:36:02 () :+ [ -z 7 ]+2018-04-26 13:36:02 () :+ [ 7 -lt 10 ]+2018-04-26 13:36:02 () :+ ((count++))+2018-04-26 13:36:02 () :+ echo 'count 8'count 8+2018-04-26 13:36:02 () :+ ./././././././././reroute.ksh+2018-04-26 13:36:02 () :+ [ -z 8 ]+2018-04-26 13:36:02 () :+ [ 8 -lt 10 ]+2018-04-26 13:36:02 () :+ ((count++))+2018-04-26 13:36:02 () :+ echo 'count 9'count 9+2018-04-26 13:36:02 () :+ ././././././././././reroute.ksh+2018-04-26 13:36:02 () :+ [ -z 9 ]+2018-04-26 13:36:02 () :+ [ 9 -lt 10 ]+2018-04-26 13:36:02 () :+ ((count++))+2018-04-26 13:36:02 () :+ echo 'count 10'count 10+2018-04-26 13:36:02 () :+ ./././././././././././reroute.ksh+2018-04-26 13:36:02 () :+ [ -z 10 ]+2018-04-26 13:36:02 () :+ [ 10 -lt 10 ]+2018-04-26 13:36:02 () :+ echo 'Out of it!'Out of it!+2018-04-26 13:36:02 () :+ echo 'count back! 10'count back! 10+2018-04-26 13:36:02 () :+ exit 0+2018-04-26 13:36:02 () :+ echo 'Out of it!'Out of it!+2018-04-26 13:36:02 () :+ echo 'count back! 10'count back! 10+2018-04-26 13:36:02 () :+ exit 0+2018-04-26 13:36:02 () :+ echo 'Out of it!'Out of it!+2018-04-26 13:36:02 () :+ echo 'count back! 9'count back! 9+2018-04-26 13:36:02 () :+ exit 0+2018-04-26 13:36:02 () :+ echo 'Out of it!'Out of it!+2018-04-26 13:36:02 () :+ echo 'count back! 8'count back! 8+2018-04-26 13:36:02 () :+ exit 0+2018-04-26 13:36:02 () :+ echo 'Out of it!'Out of it!+2018-04-26 13:36:02 () :+ echo 'count back! 7'count back! 7+2018-04-26 13:36:02 () :+ exit 0+2018-04-26 13:36:02 () :+ echo 'Out of it!'Out of it!+2018-04-26 13:36:02 () :+ echo 'count back! 6'count back! 6+2018-04-26 13:36:03 () :+ exit 0+2018-04-26 13:36:03 () :+ echo 'Out of it!'Out of it!+2018-04-26 13:36:03 () :+ echo 'count back! 5'count back! 5+2018-04-26 13:36:03 () :+ exit 0+2018-04-26 13:36:03 () :+ echo 'Out of it!'Out of it!+2018-04-26 13:36:03 () :+ echo 'count back! 4'count back! 4+2018-04-26 13:36:03 () :+ exit 0+2018-04-26 13:36:03 () :+ echo 'Out of it!'Out of it!+2018-04-26 13:36:03 () :+ echo 'count back! 3'count back! 3+2018-04-26 13:36:03 () :+ exit 0+2018-04-26 13:36:03 () :+ echo 'Out of it!'Out of it!+2018-04-26 13:36:03 () :+ echo 'count back! 2'count back! 2+2018-04-26 13:36:03 () :+ exit 0+2018-04-26 13:36:03 () :+ echo 'Out of it!'Out of it!+2018-04-26 13:36:03 () :+ echo 'count back! 1'count back! 1+2018-04-26 13:36:03 () :+ exit 0
-
Hi.
You can not change line ${this_dir}/$0
You script will work with this line.
Correct line:
$0
With ./$0 - you see that path increasing ./././././././././././reroute.ksh
With current and old setting - you script will not work in case you run it with absolute path.
/home/c037024/reroute.ksh
Regards,
Nik
-
One reason to like bash:
$ /home/oracle/aa
/home/oracle/aa
aa
$ cat aa
#/bin/bash
echo $0
echo ${0##*/}
-
With ./$0 - you see that path increasing ./././././././././././reroute.ksh
Yeah, I kind of like that it does that. It's like it's literally illustrating what happens during recursion. With every "re"- call you add another "nested" level.
-
You know what "Dude!"? That's good advice. I've just been initializing my script with #!/bin/ksh for so long it just became kind of a habit. I'm going to start using #!/bin/bash from now on just like you said, NOT "to increase your odds" of having an issue caused by the shell.
A minor point, but a good one!
Thanks Bud!
Tater