如何从ruby脚本中的(终端)cd文件夹中

时间:2011-05-25 22:08:30

标签: ruby

我想知道是否可以从我正在执行ruby脚本的位置更改当前终端目录。

例如,如果我在终端中从$HOME执行脚本,我想在脚本末尾的$HOME/mydir中cd。

我尝试了几件事,但我总是在脚本开始的同一个导演中找到。

我尝试过的事情:

Dir.chdir( mydir )
%[cd mydir]

他们实际上是在更改目录,但只在脚本执行的线程中。当脚本结束时,我在终端中的当前位置仍然与启动脚本之前的位置相同。

我在SO中发现了类似的东西,但它是Python-related,反应似乎是否定的。


你可能会问为什么?

我目前参与了一个命令行应用程序(使用gli),作为起点,需要一个项目文件夹。所以我的第一个命令如下:

$ myfoo new project

在当前目录中创建名为project的新文件夹。现在能够使用我需要的其他命令:

$ cd project
project$ myfoo domore

所以我只是认为在执行project之后在myfoo new project找到我的自我会很好。


我害怕,这并不容易(根本不可能)。那么使用一个执行我想要的ruby调用的bash脚本代替RubyGems生成的标准文件呢?这可行吗?我傻了吗?我应该使用eval吗?


感谢您的回答。但我担心没人接受。可能问题不是:)。

4 个答案:

答案 0 :(得分:2)

据我所知,这是不可能的,因为它们是不同的过程。如果你需要影响Ruby脚本的父进程(Bash),Bash需要提供一些东西。所以你可以让你的Ruby脚本输出一些bash命令,然后有一个Bash包装器来源Ruby的输出。

以Bash:

为例
`ruby -e 'puts "cd /tmp"'` | source /dev/stdin

But this will only work in Bash 4.0.

编辑:

实际上,您可以使用eval而不是Bash 3中的源代码执行此操作:

eval $(ruby -e'puts "cd /tmp"')

答案 1 :(得分:2)

我怀疑有一种直截了当的方法可以做到这一点。

当您从登录shell启动程序时,它正在执行fork / exec,这意味着创建了一个新的(子)进程(具有自己的环境,例如当前工作目录)并且它是标准输入/输出/错误流与(父)shell进程相关联。因此,当您的脚本调用Dir.chdir时,它会更改脚本(子)进程的当前工作目录,而不是父进程。

也许您的脚本可以在退出之前启动 new shell,因此看起来您的终端已更改目录。虽然,在退出终端会话之前,您必须退出该额外的shell ...

答案 2 :(得分:1)

也许稍微容易一些,

您可以将exec与Maerics结合使用,以便在ruby中创建一个新的bash shell来实现此目的。

exec ruby -e "Dir.chdir( 'mydir' ); exec 'bash'"

exec将使用子进程(ruby)替换父进程(shell),因此shell不再存在(无需退出)。

在ruby例程结束时,bash在新目录中被激活(这次再次使用exec在ruby中)并替换ruby进程。

答案 3 :(得分:0)

Midnight Commander通过使用shell别名和包装脚本来完成此任务。

包装器用于cd到由出口处mc(1)写入的文件内容确定的目录,别名用于source包装器,这使得它在登录时执行shell,而不是已经分叉的子shell,脚本已正常启动。

总而言之,这可以让它在退出时更改当前的工作目录。

为此,您需要复制别名/包装器功能。请参阅http://midnight-commander.org/browser/contrib了解他们是如何做到的。