我想知道是否可以从我正在执行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
吗?
感谢您的回答。但我担心没人接受。可能问题不是:)。
答案 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了解他们是如何做到的。