我知道我能做什么外壳程序或者获取脚本而不是运行它到cd
我正在使用的外壳。我想知道的就在那里任何到“父外壳”的方式cd
(不确定这是否是正确的短语)。
#!/bin/sh
# This is script.sh
cd $1
pwd
这是一些输出。 (笔记:这不是确切的输出,我只是通过删除不必要的细节来缩短它。我在 shell 中输入的行以 开头>
。)
> mkdir foo
> ./script.sh foo
/home/myName/foo
> pwd
/home/myName
据我了解,这是预期的行为。这是我“获取”脚本的情况。
> . ./script.sh foo
/home/myName/foo
> pwd
/home/myName/foo
如果不获取脚本也不将其设为 shell 过程,有什么方法可以./script.sh foo
在目录中使用的 shell 中输入结果吗/home/myName/foo
?
答案1
不会,因为当您将脚本调用为 时./script.sh foo
,它会启动一个子 shell 来为您运行该脚本。当该子 shell 退出时,您将返回到启动该脚本时所在的目录。不过,您可以通过使用执行如下操作的脚本来伪造此行为:
#!/bin/bash
cd $1
bash
更改目录后,这将使您进入子 shell,然后您必须exit
返回到原始 shell。
如果你改为最后一行:
exec bash
您不必退出新 shell,因为新 shell 将替换旧 shell。然而,这样做仍然是一个丑陋的黑客行为(恕我直言)。
答案2
简单的答案是否定的——这是不可能的。
但是,如果您绝望,您可能会找到一些解决方法。
最简单的方法是当您只需要几个目录时提前知道(在父 shell 中)脚本可能尝试cd
进入的位置。在这种情况下,您可以为从脚本发送的某些信号设置陷阱。
~ $ cat script
#!/bin/bash
kill -s SIGINT "$PPID"
~ $ trap 'cd /tmp' SIGINT
~ $ ./script
/tmp $
执行此操作的一种更复杂的方法是将脚本中的命令写入父 shell 标准输入。描述了程序(相当复杂)这里,但最简单的情况(提前定义目录)也很简单:
~ $ cat script
#!/bin/bash
printf '\e[5n' >/proc/"$PPID"/fd/0
~ $ bind '"\e[0n": "cd /tmp\n"'
~ $ ./script
/tmp $
如果您想将目录名称作为参数从脚本传递到父 shell,我建议您研究上面链接中的答案。
答案3
你可以试试:
gdb --batch -ex 'call chdir("/some/dir")' -p "$PPID"
但我预计大多数 shell 在当前目录发生变化时都会感到困惑。
顺便说一句,在 shell 语法中,您需要在变量周围加上引号并将--
选项与参数分开。另请参阅cd
未通过时的特殊行为-P
。所以你的代码应该更像是:
#! /bin/sh -
cd -P -- "$1"
例如,相当于int main(int argc, char*argv[]){chdir(argv[1])}
C 语言(在更改另一个进程的当前目录时仍然无效)
答案4
脚本在子 shell 中运行,任何环境更改(目录和变量)都是该进程的本地更改,并在进程退出(或以其他方式交回控制权)时恢复到调用进程的环境更改。
您可以运行命令在当前外壳中(因此它们的效果仍然存在)通过获取脚本 ( . here/is/the/script
) 或定义 shell 函数。 Shell 函数可能非常复杂,而且最重要的是,它们是在当前 shell 进程中执行的。并非所有 shell 都支持函数(bash 支持)。