Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have a bash script foocaller, which calls a ruby script foo:

foocaller

/path/to/foo

Within foo, I want to get the path of foocaller. Following this suggestion, I put the following code to do that:

foo

#!/usr/bin/env ruby
puts File.read("/proc/#{Process.ppid}/cmdline")

When I run:

$ bash foocaller

then I get the desired:

bash^@/path/to/foocaller

but when I directly call foocaller:

$ foocaller

then I get this:

/bin/bash^@--noediting^@-i

which does not show the path to foocaller. How can I get the path to foocaller by directly calling foocaller without bash?

share|improve this question
    
What is your OS and ruby version? I use Fedora and it works fine. –  Gnouc Jun 15 at 16:32
    
@Gnouc OS is Ubuntu. Ruby version is irrelevant. –  sawa Jun 15 at 16:48
    
Add a exit at the end your foocaller script, otherwise, foocaller may execute foo in the same process. –  Stéphane Chazelas Jun 15 at 19:01

1 Answer 1

up vote 3 down vote accepted

Many shells optimise the last command in a script by executing the command in the same process:

$ sh -c 'ps
ps'
  PID TTY          TIME CMD
32673 pts/3    00:00:00 zsh
32696 pts/3    00:00:00 sh
32697 pts/3    00:00:00 ps
  PID TTY          TIME CMD
32673 pts/3    00:00:00 zsh
32696 pts/3    00:00:00 ps

See how the second ps was executed in the process that initially ran sh (32696), and then its parent is the sh's parent (in my case here, zsh my interactive shell).

You can avoid that by adding an exit line:

#! /bin/sh -
foo
exit

sh cannot execute foo in the same process because, it still has more to interpret after foo has finished. So it will instead run foo in another process and wait for it. And then run exit (which will exit the script with the same exit status as that of foo).

Now, that's not very optimal, as you could have saved a process here.

A better way to have foo know about the path of foocaller could be to tell it:

#! /bin/sh -
CALLER=$0 foo

Then foo can query the CALLER environment variable to get the path of its caller (import os;print(os.environ["CALLER"]) in python)

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.