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

Shell 如何更改运行可执行文件的父工作目录?,shell,haskell,directory,optparse-applicative,Shell,Haskell,Directory,Optparse Applicative,我的项目是Haskell中的一个命令行应用程序,它使用应用程序包来处理命令行选项的解析 我正在尝试实现一个功能,该功能可以更改运行命令的shell的工作目录 例如,我想做一些像 $ program foo 并将shell更改为我的程序与传递的选项foo关联的指定目录 $ program foo input 'foo'; now changing to directory '~/mydirectories/foodirectory' [~/mydirectories/foodirectory]$

我的项目是Haskell中的一个命令行应用程序,它使用应用程序包来处理命令行选项的解析

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

例如,我想做一些像

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

$ program foo
input 'foo'; now changing to directory '~/mydirectories/foodirectory'
[~/mydirectories/foodirectory]$
我尝试使用
目录
包中的函数实现此功能,但是这似乎不会影响运行目录的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)”
放在他们的点文件中,但随后将具有所需的功能。

一般来说,您不能这样做。任何程序都不能使用标准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)”
放在他们的点文件中,但随后将具有所需的功能。

不是shell限制或Haskell限制--您也不能用C编写一个程序来更改启动它的单独C程序的目录,没有父进程的积极参与,或使用调试器接口或类似的工具。@CharlesDuffy我明白了,谢谢。似乎我不需要更改目录,而是必须打印出路径,以便用户可以复制并
cd
。出于好奇,
cd
program命令如何更改目录?
cd
不是一个单独的程序,它是一个shell内置程序
/usr/bin/cd
可能存在于您的操作系统上,但实际上无法更改调用它的shell中的目录。
cd
是shell内置的,好吧。不是shell限制或Haskell限制——您也不能用C编写程序来更改启动它的单独C程序的目录,没有父进程的积极参与,或使用调试器接口或类似的工具。@CharlesDuffy我明白了,谢谢。似乎我不需要更改目录,而是必须打印出路径,以便用户可以复制并
cd
。出于好奇,
cd
program命令如何更改目录?
cd
不是一个单独的程序,它是一个shell内置程序
/usr/bin/cd
可能存在于您的操作系统上,但实际上无法更改调用它的shell中的目录。
cd
是shell内置的,好吧。