如果在 bash 脚本中使用,`cd` 不起作用

如果在 bash 脚本中使用,`cd` 不起作用

cd在 Bash 脚本中使用它时,我无法再使用它

[~/Downloads] # cat cd-backward
#!/bin/bash
cd ..

[~/Downloads] # ./cd-backward
[~/Downloads] #

我应该移至~最后一行。

cd奇怪的是,它在终端上运行良好。bash -c 'cd Download例如,当我运行时也没有发生任何事情。

答案1

每个脚本都以自己的方式执行subshell,这是一个单独的进程,无法修改其父母工作目录。使用写入文件的脚本更改工作目录的唯一方法是使用.source(它们是等效的)来获取它,如下所示:

$ . cd-backward

或者

$ source cd-backward

请注意,在这种情况下,您甚至不需要在脚本顶部使用shebang( )。#!/bin/bash

答案2

当你启动一个脚本时,它会在它有自己的壳,正如 Arkadiusz 已经提到的那样。在这种情况下,您有 的实例bash。如果您修改脚本,您可以看到它:

#!/bin/bash
cd ..
pwd

在我的系统上运行示例得到:

bash-4.3$ pwd
/home/xieerqi/Downloads
bash-4.3$ ./cd-backward 
/home/xieerqi
bash-4.3$ pwd
/home/xieerqi/Downloads

非常恰当的是,在脚本子 shell 中,您可以导航到主目录。但是,父 shell 的当前工作目录保持不变

答案3

您的进程(称为$$)有一个“当前目录”,~/Downloads

当你 时./cd-backward,该 Bash 脚本将在其自己的进程中运行,该进程有自己的“当前目录”,以 开始~/Downloads

影响进程cd ..的“当前目录” ./cd-backward,将其更改为~,但不会影响原始进程的“当前目录”。

./cd-backward完成后,其进程退出,并被cd ..遗忘。

以下是我影响保存在‘~/.bashrc’中的“当前目录”的两种方法:

首先,有几个alias

alias ..='cd ..'
alias ...='cd .. ; cd ..'

以下是我如何将当前目录保存在窗口标题中(通过拦截cd):

# from the "xttitle(1)" man page - put info in window title
update_title()
{
    [[ $TERM = xterm ]] || [[ $TERM = xterm-color ]]  && xttitle "[$$] ${USER}@${HOSTNAME}:$PWD"
}

cd()
{
    [[ -z "$*" ]] && builtin cd $HOME
    [[ -n "$*" ]] && builtin cd "$*"
    update_title
}

相关内容