ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
My own is it should be avoided. As I think recursion is being done by sub shell calls. But then there is problem with script termination cause Ctrl+C kills only low bottom shell. But maybe I am mistaken. I think it is not harmful if from very beginning it is known that recursion is never deep. Here balance is simple code with recursion against more complicated code without recursion. It is not only theoretical problem. I just recently have seen bash script with recursion - I am not quite sure what to think about this and only my own opinion can be biased.
Mostly recursion is realized with a function - not with calling the own script as a sub shell.
A call to a function only puts something on a stack.
If local variables are used in the function then you can realize powerful things with recursion.
I use plenty of functions in shell scripts. I can't think of any that call themselves though. I guess I just haven't had any use cases for such a thing when writing in shell (bash or bourne shell). I have written a script that takes parameters, and can call itself with a "--child" parameter, which makes the child backgrounded invocation act differently, and then sets a number of traps to receive signals from the master script. I was rather fond of it but I ultimately rewrote that architecture so it's not in use anymore with the self-calling script.
Sort of recursion: a script might check the running user: if it is `root` then execute itself with `su - oracle -c "$0 $@"` to switch to the correct user.
again a useless pseudo-theoretical question?
recursion itself is fine, as long as it is correctly implemented. There is nothing wrong with it. The language itself is completely irrelevant.
The following is an example for recursion with a function:
Code:
#!/bin/bash
# check_file_queues.sh - Nagios plugin
# checks the #files in /var/{spool,log,adm,crash,opt} and subdirectories
# skips NFS-mounted sub dirs and prunes at a depth of 4
set +f
PATH=/bin:/usr/bin:/usr/sbin:/sbin
export PATH
case $1 in
(-*) echo "Usage: $0 [#files]"; exit 3;;
(*[!0-9]*) echo "$0: '$1' is not an integer"; exit 3;;
esac
maxfiles=${1:-1000}
for mtab in /etc/mnttab /etc/mtab /proc/mounts
do
[ -r $mtab ] && break
done
if [ ! -r $mtab ]
then
mtab=/tmp/mtab.$$
trap "rm -f $mtab" 0 HUP INT SYS
mount | awk '$1~/^\//' > $mtab
fi
nfsmnt=`awk '($2~/^\/var\// && $3=="nfs") {printf " %s ", $2}' $mtab`
rdepth=0
recurse(){
local i cnt=0
for i in "$1"/*
do
[ -h "$i" ] && continue
if [ -d "$i" ]; then
[ $((rdepth++)) -lt 4 ] && [[ $nfsmnt != *" $i "* ]] && recurse "$i"
((rdepth--))
else
((cnt++))
fi
done
if [ $cnt -ge $maxfiles ]; then
echo "WARNING: $1 has $cnt files"
exit 1
fi
}
recurse /var/spool
recurse /var/log
recurse /var/adm
recurse /var/crash
recurse /var/opt
echo "OK: less than $maxfiles files in /var dirs"
Sort of recursion: a script might check the running user: if it is `root` then execute itself with `su - oracle -c "$0 $@"` to switch to the correct user.
Wow, thanks. This is exactly what I was looking for
I have built both kinds of solutions using BASH or KSH in different environments: using recursive functions or a script that called itself. It is more important in a script using recursion to limit the levels of recursion than in a compiled language, but it is important in both. The important point is not "it uses recursion", it is that it solves the problem and avoids adding new issues or vulnerabilities. I was a bit surprised when I discovered just how powerful BASH could be as a tool to solve problems I would otherwise have used C or JAVA to address, and lighter, faster, and more maintainable than either for certain specific cases.
Lessons: 1. never do recursion for recursions sake. Only use it when you need it to solve the problem, or when it generates the BEST solution. 2. Do not fear your tools, understand them. Never be afraid to use what they can do for you. 3. never neglect your error checking or avoidance, even for a prototype. I cannot enumerate how many "first draft" solutions I saw go into production because the fell into a managers hands before they were ready. After this many years I can now laugh at the results, but in the moment it is NOT funny. Avoid this scenario.
Personally I wouldn't do any programming in shell apart from very general stuff.
Why not use a better tool for the job?
It's just amateur
hm. although it is completely offtopic here, shell is the best tool in a lot of cases.
Obviously it has some limitations, and there are cases, when you need another language. But otherwise you can definitely write even professional programs in shell.
Arguably the whole of most GNU/Linux installations could be called amateur :/
But then, one should check one's /usr/bin, /usr/sbin and what have you directories for shell scripts:
Code:
for i in /usr/*bin/*; do [ -f "$i" ] && [ -x "$i" ] && head -1 "$i" | grep -I '^#.*sh'; done
Arguably the whole of most GNU/Linux installations could be called amateur :/
But then, one should check one's /usr/bin, /usr/sbin and what have you directories for shell scripts:
Code:
for i in /usr/*bin/*; do [ -f "$i" ] && [ -x "$i" ] && head -1 "$i" | grep -I '^#.*sh'; done
A better test would involve "file". Something as simple as
Code:
file /usr/bin/* | grep shell
will find all of the shell scripts. Sonce the BASH scripts are identified as "Bourne-Again shell script" in my version, my identification of bash shells in a folder might look like
Code:
file /usr/bin/* | grep Bourne
One should not, however, expect to find any examples of recursion in those scripts.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.