2011-05-25 67 views
8

我想知道是否有可能從我正在執行我的ruby腳本的位置更改當前終端目錄。如何從ruby腳本中的(終端)cd文件夾

例如,如果我在終端中執行$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

這似乎不太可能。來自ruby的任何系統調用都在與腳本/外殼不同的線程中運行,並且不會影響當前位置。你希望用它來做什麼? – 2011-05-25 22:11:53

+0

@ Douglas-F-Shearer:出於好奇,我在理由 – 2011-05-25 22:18:57

+0

中有一點延伸,爲什麼我的答案沒有奏效?我已經多次使用過這種技術,但我不清楚它如何不適合您的情況。 – Ian 2011-05-26 21:43:57

回答

2

據我所知,這是不可能的,因爲它們是不同的過程。如果你需要影響Ruby腳本的父進程(Bash),Bash需要提供一些東西。因此,您可以讓您的Ruby腳本輸出一些bash命令,然後使用源代碼的Ruby輸出的Bash包裝器。

嘗試以此爲例,在擊:

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

But this will only work in Bash 4.0.

編輯:

其實,你可以使用EVAL代替源猛砸3做到這一點:

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

好吧,但我在'%[eval $(ruby -e'puts「cd/tmp」')]'腳本結束,這沒有什麼區別。 – 2011-05-25 22:37:41

+0

沒錯,因爲你正在產生一個孩子Bash進程(你想影響Bash進程的孫子),在你的代碼中進行評估,然後讓它死亡。您需要直接在您想要更改的Bash進程中運行eval。稍後,你可以用別名或其他東西來整理它。 – Ian 2011-05-25 22:43:45

+0

我已經擴展了以相反方式詢問事情的答案。 – 2011-05-25 22:56:55

2

我懷疑有一個簡單的方法來做到這一點。

當你從登錄shell啓動一個程序時,它會在一個fork/exec下創建一個新的(子)進程(它有自己的環境,比如當前的工作目錄),它是標準的輸入/輸出/錯誤流與(父)shell進程相關聯。因此,當您的腳本調用Dir.chdir時,它會更改腳本(子)過程的當前工作目錄,而不是父級。

也許您的腳本在退出之前可能會啓動一個新的 shell,因此它看起來像您的終端已更改目錄。雖然,在退出終端會話之前,您必須退出額外的外殼...

+0

我已經擴展了相反的問題的答案。 – 2011-05-25 22:57:01

0

Midnight Commander通過使用shell別名和包裝腳本執行此操作。

封裝器用於cd'ing到由mc(1)在退出時寫入的文件的內容確定的目錄,該別名用於source封裝器,該封裝器使其在登錄shell中執行,而不是如果腳本已正常啓動,將會分叉的子shell。

總而言之,這可以讓它在退出時更改當前工作目錄。

要做到這一點,你需要複製別名/包裝功能。請參閱http://midnight-commander.org/browser/contrib瞭解他們是如何做到的。

+0

是否有一些文件?我如何將這個應用於我的用例? – 2011-05-25 22:58:54

+0

這與我的回答是一樣的。 – Ian 2011-05-25 23:59:00

1

也許稍微容易些,

您可以結合使用EXEC與Maerics後關於Ruby的內部創建一個新的bash shell來實現這一目標。

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

exec將與子進程(紅寶石)代替父進程(殼),從而殼不再存在(無需退出)。

在ruby例程bash的最後,在新目錄中啓動(這次再次使用exec),並替換ruby進程。

+0

我如何將它與具有自己命令的rubygem結合起來,就像答案中所描述的那樣? – 2011-05-25 23:13:53

+0

@empo最後,ruby腳本添加'exec'bash''。在命令行中,將該調用修改爲'exec myfoo new project'。儘管如此,這仍然很笨重 – diedthreetimes 2011-05-25 23:29:56

相關問題