[prog] Returning a string from a function, in bash

Riccarda Cassini riccarda.cassini at gmx.de
Fri Apr 16 20:11:09 EST 2004


Hi Sue,  thanks for your comments!

> What the backticks do really is present the output from a program (which
is 
> outside of the current script) as arguments.  So you do need to have 
> something to pass them as arguements to ... in this case you have used
echo 
> to print them.

I had never worked with functions in shell scripts before. So, I simply
tried to generalise from what I knew from perl. As there are some other
similarities, I thought that functions would roughly work the same way,
too (which in the process of playing around with it, turned out to be a
little naive).

Along similar lines, I tried to transfer my notion of what backticks
do to shell scripting. As I understand, they capture the output of a
seperately run program in a string, instead of having it go to STDOUT.

I was told that running an external program (as a new process) involves
two system calls (fork/exec), which are rather expensive, compared to
simply calling a function within the same process. This kind of led me
to avoid backticks whenever possible. (Mind you, I don't really know
what I'm talking about, so don't nail me down on that ;-)

In the meantime, I read somewhere in the bash manpage, that using
backticks to call *functions*, does not actually involve creating a
new process. Well, when thinking about it, it somehow makes sense...
(what should be run in that new process - the script itself again?)
However, I'm not entirely sure I understood this correctly.

Anyway, that's essentially why it took me quite a while to give up
this idea that there must be some simpler, more direct way to pass
around that return string...  But I think, I finally got it :-)


> You originally said that you wanted to return the result as some variable.
>  
> All you have done here is to print out the result of the program that you 
> have run, not assign it to a variable.  

Actually, I wanted to do something slightly more sophisticated...:

What originally got me started on this was that recent thread here
on how to determine whether some script is run by 'init'.  One of
the suggested approaches was to take a look at the PPID - or, more
precisely, the 'grand parent' process ID of the script being run.

I like puzzles, so I started playing around... I thought there must be
some combination of the multitude of options there are to 'ps', which
simply returns the PPID for a given PID (without any output parsing
with awk and stuff). Applying that repeatedly could get you any PID
up in the process hierarchy.  I figured out that this can be done with

  ps -p $PID -o ppid --no-headers

That's rather nice as a first step, but it would even be nicer to have
this wrapped up in some function, so you could write something like

  $GPPID = ppidof(ppidof($$));

Even with my limited knowledge of perl, it wasn't too difficult to come
up with an appropriate function doing just that:

  sub ppidof
  {
    my $pid = shift;
    chomp $pid;
    return `ps -p $pid -o ppid --no-headers`;
  }

But the original task required you do this in shell, not perl ;-)
So, if you're still with me, you'll see that at this point the real
challenge began for me.  What I set out to achieve (in shell code) was:

  GPPID=ppidof(ppidof($$))

which, as we all know in the meantime, doesn't work that way ... ...


Well, now you at least have an idea what a wannabe hacker does when she 
has nothing else to do in the evening :-)

(Btw, thanks to whoever initiated that 'init' thread - I've learnt
quite a lot, indirectly :-)

Riccarda



-- 
NEU : GMX Internet.FreeDSL
Ab sofort DSL-Tarif ohne Grundgebühr: http://www.gmx.net/info



More information about the Programming mailing list