Reputation: 24836
I'd like to know if it's possible to change the current terminal directory from where I'm executing my ruby script.
For example, if I'm executing the script from $HOME
in the terminal, I would like to cd in $HOME/mydir
at the end of the script.
I've tried a couple of things, but I'm always finding in the same directorry where the script was started.
Things I've tried:
Dir.chdir( mydir )
%[cd mydir]
They actually do change directory, but only in the thread of the script execution. When the script ends, my current location in the terminal is still the same I was before launching the script.
I've found something similar in SO, but it's Python-related and response seems negative.
You may ask why?
I'm currently involved in a command line application (using gli
) which, as starting point, needs a project folder. So my first command looks like:
$ myfoo new project
Which creates a new folder with name project
in the current directory. Now to be able to work with the other commands I need to:
$ cd project
project$ myfoo domore
So I was simply thinking that it would be nice to found my self in project
after having executed myfoo new project
.
As I was afraid, it's not that easy (not possible at all). So what about using a bash script which does the ruby calls that I want, in place of the standard file generated by RubyGems? Is that feasible? Am I foolish? Should I use eval
?
Thanks for the answers. But I'm afraid that no one is acceptable. Probably the question wasn't :).
Upvotes: 8
Views: 3176
Reputation: 4113
Maybe slightly easier,
You can use exec in combination with Maerics post about creating a new bash shell inside of ruby to achieve this.
exec ruby -e "Dir.chdir( 'mydir' ); exec 'bash'"
exec
will replace the parent process(shell) with the child process (ruby), thus the shell no longer exists (no need to exit).
At the end of the ruby routine bash is fired up (again with exec
this time in ruby) in the new directory and replaces the ruby process.
Upvotes: 1
Reputation: 1
Midnight Commander does this, by using a shell alias and a wrapper-script.
The wrapper is for cd'ing to a directory determined by the contents of a file written by mc(1) at exit, and the alias is used to source
the wrapper, which makes it execute in the login shell, instead of the subshell that would have been forked, had the script been launched normally.
All in all, this lets it change the current working directory on exit.
To do this, you'd need to duplicate the alias/wrapper functionality. See http://midnight-commander.org/browser/contrib for how they did it.
Upvotes: 0
Reputation: 156642
I doubt there is a straightforward way to do this.
When you launch a program from your login shell, underneath the hood it's doing a fork/exec which means a new (child) process is created (which has its own environment, such as current working directory) and it's standard input/output/error streams are associated with the (parent) shell process. So when your script calls Dir.chdir
it changes the current working directory for the script (child) process, not the parent.
Perhaps your script could launch a new shell before it exits, so it looks like your terminal has changed directory. Although, you'd have to exit from that extra shell before exiting your terminal session...
Upvotes: 2
Reputation: 2108
This isn't possible, to my knowledge, since they're different processes. If you need to affect the Ruby script's parent process (Bash), Bash will need to source something. So you could have your Ruby script output some bash commands, then have a Bash wrapper that source's Ruby's output.
Try this as an example, in Bash:
`ruby -e 'puts "cd /tmp"'` | source /dev/stdin
But this will only work in Bash 4.0.
EDIT:
Actually, you can do this with eval instead of source in Bash 3:
eval $(ruby -e'puts "cd /tmp"')
Upvotes: 2