As other answers have pointed out, running either system("cd foo")
or `cd foo`
within a Ruby script will only change the directory of the Ruby subprocess. As soon as the Ruby script finishes, you'll get popped back to the directory you were in before.
A way around this is to have the Ruby script only be responsible for printing out a directory name and then calling that script with a wrapping shell function that cd
s into the directory the Ruby script prints out.
If you'd like your Ruby script to interact with the user use STDERR.puts
instead of puts
.
Here's an example Ruby script cd.rb
that will try to find a matching directory from user input:
#!/usr/bin/env ruby
pattern = ARGV.join(" ")
dirs = Dir.glob("*").filter{|path| File.directory?(path)}.filter{|path| path.include?(pattern)}
if dirs.length == 0
STDERR.puts "Error: no matching directories found."
print "."
exit 1
elsif dirs.length == 1
print dirs.first
else
while true do
STDERR.puts "Which one?"
dirs.each_with_index{|dir, i|
STDERR.puts "#{i+1}. #{dir}"
}
STDERR.print "=> "
i = STDIN.gets.chomp.to_i - 1
if dirs[i]
print dirs[i]
exit
else
STDERR.puts "Error: uhh what? Try that again...\n\n"
end
end
end
And here's the wrapping sh
or zsh
script to stick in your .bashrc
or .zshrc
that will pass along arguments to cd.rb
and then cd
into the directory that Ruby script prints out:
function ,cd () {
cd "`cd.rb $@`"
}