3

In Script to change current directory (cd, pwd) it is shown how to run a bash script that changes terminal directory.

But how do i run a perl script that runs a bash script that changes terminal directory?

john-jones
  • 1,736

5 Answers5

9

You can't.

The Perl script runs in a process which is a child of your shell session. This child process can change its own working directory all it likes, but it cannot change it's parent's working directory. When the Perl script exits, control is returned to the parent process (the shell session), which will have remained in the same working directory the whole time, regardless of what the child process did while it was running.

5

You can't do this directly. The only way for a shell to change its current directory is for the shell itself to execute a cd command (or pushd, popd, etc.).

But you can do it indirectly. Here's a simple example that change the current directory to /tmp:

cd-tmp.pl:

#!/usr/bin/perl

print "cd /tmp\n";

In your .bashrc or .bash_profile:

cd-tmp() { eval $(cd-tmp.pl); }

This assumes that cd-tmp.pl is in a directory in your $PATH -- or you can specify the full path in the function.

When you type cd-tmp at your shell prompt, it invokes cd-tmp.pl, captures its output, and executes that output as a shell command.

A Perl script can't cause a calling shell to change directories, but it can provide it with a command that the shell can then execute itself.

Of course you can use a directory other than /tmp, including one that's determined based on other information or created on the fly.

One point of clarification: the current directory is a property of the current shell process, not of the terminal.

UPDATE :

I just realized that I missed part of your question; you want "a perl script that runs a bash script". It's easy enough to modify my example to do that, but I have no idea why you need the Perl script to run a bash script. You haven't told us nearly enough about what you're actually trying to accomplish.

0

There are multiple ways (TIMTOWTDI) of executing external commands from Perl. Like using exec(), using backticks (``) etc. If you can run the external commands right from your Perl script then I think there is no need to call another Bash script (but you can do that too). Follow the link below to learn more. Also note, any changes made within the program affects only the subshell and remains effective throughout the program only, which is always a good thing, but there are ways that you can make the changes permanent i.e. it would affect the parent shell as well.

http://www.perlhowto.com/executing_external_commands

UPDATE-

Some questions on "How to do it in other ways". For unusual requirements there ought to be unusual solutions (that work). But the question is why would you use Perl to change parent shell directory? Here's how you'd do it anyways

$cat test.pl
 print "Hello world\n";
 print "cd ..";
$pwd
 /home/user/perlcode
$eval `perl test.pl|tee -a test.pl.log|grep cd`
$pwd
 /home/user
Anjan Biswas
  • 216
  • 1
  • 3
  • 10
0

You can only do that indirectly, e.g. using aliases. Have your bash script, instead of changing to the desired directory, just print the desired directory to stdout. Perl should then capture this output and also print the desired directory to stdout. A shell alias or shell function can then take that output and change the directory inside the running shell.

An example:

a.sh:

#!/bin/bash
mkdir /tmp/$$
echo /tmp/$$

b.pl:

#!/usr/bin/perl
my $something = do_somestuff();
print `./a.sh $something`;

sub do_somestuff{
     #do some processing here
     return "";
}

Use this shell function and test it:

daku@server:/home/daku $ b() { DIR=`./b.pl`; if test -n "$DIR"; then cd "$DIR"; fi }
daku@server:/home/daku $ b
daku@server:/tmp/14397 $
daniel kullmann
  • 9,527
  • 11
  • 39
  • 46
  • Your b.pl script would be more simply written as system './a.sh' -- and it's not particularly useful, since you might as well just invoke a.sh directly. – Keith Thompson Jul 17 '12 at 18:56
  • Well, it was just for demonstration. The OP wanted to have a Perl script that runs a shell script that changes the current directory of the shell running the perl script. – daniel kullmann Jul 17 '12 at 19:26
  • Ah, I missed the "that runs a shell script" part. Which leaves an open question: Why?? – Keith Thompson Jul 17 '12 at 19:49
0

One more solution is to first save the directory you want to visit in a string variable :
Eg :

$cd_path = "/var/tmp";
$cmd_to_run = "cd $cd_path ; ls -lrt";
system($cmd_to_run);
manatwork
  • 31,277