Perl: Run perl script in the current process

I have a question regarding running perl in the current process.

I shall demonstrate with an example.

Look at this.

sh-2.05b$ pwd
/tmp
sh-2.05b$ cat test.sh
#! /bin/sh
cd /etc
sh-2.05b$ ./test.sh 
sh-2.05b$ pwd
/tmp
sh-2.05b$ . ./test.sh 
sh-2.05b$ pwd
/etc
sh-2.05b$ 

So invoking ./test.sh spawns a sub-shell and runs the script. Whereas . ./test.sh will run the script in the current shell.

Now, how can I simulate the latter behavior with a perl script. I tried the following but it did not help.

sh-2.05b$ pwd
/tmp
sh-2.05b$ cat test.pl
#! /usr/bin/perl
chdir("/etc");
sh-2.05b$ ./test.pl 
sh-2.05b$ pwd
/tmp
sh-2.05b$ . ./test.pl 
sh: ./test.pl: line 2: syntax error near unexpected token `"/tmp"'
sh: ./test.pl: line 2: `chdir("/tmp");'
sh-2.05b$ 

Is there any other way of running the script to make sure that the changes made by the script will affect the current process ?

Thanks,
Vino

AFAIK perl always creates a child.

Is there a reason you can't read the other script and do what it does in the context of the current process? ie., find the chdir and then do what it does in your perl script?

Yes, it can be done that way. That would work.

I am curious to know if it can be done this way.

Thanks,
vino

Just a guess, but I think the . command is instructing the current shell to interpret the script - which it can't because it has perl commands/functions in it.

The "exec" builtin in bash (sh on Linux seems to be too) will run the perl process without creating a new process by replacing the original shell process, just like the C exec* family of functions.

So you ought to be able to run a script by "./script.sh" to create a new process and then "exec perl script.pl" to continue execution without introducing a new process, but the original shell script will terminate (control will not return to the shell script).

On most (recent) Linux distros sh is soft/hard linked to bash...

# ls -l /bin/sh /bin/bash
-rwxr-xr-x  1 root root 616312 Dec  7  2004 /bin/bash
lrwxrwxrwx  1 root root      4 May 18  2005 /bin/sh -> bash

Hmm...okie. So I used exec. This is what I got.

sh-2.05b$ pwd
/tmp
sh-2.05b$ cat test.sh
#! /bin/sh
exec perl /tmp/test.pl
sh-2.05b$ cat test.pl
chdir("/etc");
sh-2.05b$ ./test.sh
sh-2.05b$ pwd
/tmp
sh-2.05b$ 

I did a . ./test.sh and my xterm window just disappeared.

I changed test.pl to contain

#! usr/bin/perl
chdir("/etc");

and test.sh to

#! /bin/sh
exec /tmp/test.pl

The pwd still shows /tmp.

vino

You would like the Perl script chdir() to affect the parent shell process? That is impossible in this case as exec() won't return, so when the Perl script ends, the original shell process also ends.

I'm sorry that I have probably misunderstood your question. I would say the method is only for the original process image (shell script in your case) affecting the later, replaced process image (the Perl script in your case), and doesn't work if you expect the parent environment to be influenced after exec(), as it won't return at all.

So, as I understand, whatever the perl script does will not affect the parent shell.

Say, in this case, after I change to the new directory, I cant remain in that new directory even after the perl script exits. Right ?

Absolutely correct. What you are asking: 'Can I source a file from inside perl?'
No. Because you have to call exec. This is exactly the same problem you have with shell scripts doing a cd and then exiting.

Thanks Jim.

Vino