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

How to change the parent working directory from which my executable is run?

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

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

例如,我想做这样的事情

$ program foo

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

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

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

的 shell 没有变化

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

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

一般情况下,您不能这样做。任何程序都不能更改其父进程的目录,无论它是用什么语言编写的,使用标准的 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)" 放入他们的点文件中,但此后将具有所需的功能。