如何更改运行可执行文件的父工作目录?

时间:2018-01-24 23:50:24

标签: shell haskell directory optparse-applicative

我的项目是Haskell中的命令行应用程序,并使用opt-parse applicative包来处理命令行选项的解析。

我正在尝试实现一个可以更改运行命令的shell的工作目录的功能。

例如,我想做类似

的事情
$ program foo

并将shell更改为我的程序与传递的选项foo关联的指定目录。

$ program foo
input 'foo'; now changing to directory '~/mydirectories/foodirectory'
[~/mydirectories/foodirectory]$

我尝试使用directory包中的setCurrentDirectory函数实现此功能,但这似乎不会影响运行目录的shell中的工作目录;工作目录中没有变化。我想象它正在设置某种内部到程序的工作目录,因为我看到运行可执行文件的shell没有变化。

是否可以让我的程序以这种方式更改目录?这种目录切换功能将提高使用我的应用程序的便利性。

如何从命令行可执行文件实现目录切换功能?

1 个答案:

答案 0 :(得分:4)

一般情况下,你不能这样做。没有程序可以使用标准UNIX接口更改其父进程的目录,无论它使用何种语言编写。程序只能更改自己的目录(并且,通过扩展,它可以更改它随后启动的任何程序的初始工作目录)。

但是,有了shell的积极参与,你可以做一些非常相似的事情。考虑指示您的用户运行shell函数,如下所示:

# this wrapper works on any POSIX shell, but will avoid setting a global variable "dir" if
# the active shell (like bash, ksh, or even dash) supports local variables.
chdirWithMyHaskellProgram() {
    local dir 2>/dev/null || \
      declare dir 2>/dev/null || \
      : "current shell does not support local variables; proceeding anyhow"
    dir="$(myHaskellProgram "$@")" && cd -- "$dir"
}

...将导致chdirWithMyHaskellProgram --foo-bar调用myHaskelProgram --foo-bar,并且当且仅当退出状态表示成功时,才会切换到输出中指定的目录。

考虑让myHaskelProgram --eval向上述函数发出源代码。如果你实现了这个,那么你的用户需要将eval "$(myHaskelProgram --eval)"放在他们的dotfiles中,但之后会有所需的功能。