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

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

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

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

我尝试过的事情:

 Dir.chdir( mydir ) %[cd mydir] 

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

我在SO中发现了类似的东西,但它与Python相关并且响应似乎是否定的。


你可能会问为什么?

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

 $ myfoo new project 

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

 $ cd project project$ myfoo domore 

所以我只是觉得在执行myfoo new project之后在project找到自己会很好。


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


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

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

以Bash为例,试试这个例子:

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

但这只适用于Bash 4.0。

编辑:

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

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

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

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

也许你的脚本可以在它退出之前启动一个 shell,所以看起来你的终端已经改变了目录。 虽然,在退出终端会话之前,您必须退出该额外的shell …

也许稍微容易些

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

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

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

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

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

包装器用于cd到由出口处由mc(1)写入的文件内容确定的目录,并且别名用于获取包装器,这使得它在登录shell中执行,而不是在子shell中执行如果脚本正常启动,它会被分叉。

总而言之,这允许它在退出时更改当前工作目录。

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