为什么“cd”不能在shell脚本中工作?
我只想写一个更改我的目录的脚本。
我将以下命令放在文件/home/alex/pathABC
#!/bin/sh cd /home/alex/Documents/A/B/C echo HelloWorld
我做了chmod +x pathABC
。
在终端中,在/home/alex
,我运行./pathABC
,但输出只是HelloWorld
,并且当前目录没有更改。
那有什么不对?
正如其他人所解释的那样,目录在脚本的子进程中更改,而不是在调用脚本的终端进程中更改。 在子进程终止后,您将返回到终端所在的位置。
几种选择:
1.符号链接
将符号链接放在您想要轻松访问的长路径中
$ ln -s /home/alex/Documents/A/B/C ~/pathABC
然后访问目录:
$ cd ~/pathABC
别名
在〜/ .bashrc中添加别名:
alias pathABC="cd /home/alex/Documents/A/B/C"
(从这里 )
3.function
创建一个更改目录的函数,该函数在终端的进程中运行,然后可以更改其目录。
(从这里 )
4.避免像孩子一样跑步
来源你的脚本而不是运行它。 Sourcing(由.
或source
)会导致脚本在同一个shell中执行,而不是在自己的子shell中运行。
$ . ./pathABC
(从这里到这里 )
5. cd-able vars
在~/.bashrc
设置cdable_vars
选项,并为目录创建一个环境变量:
shopt -s cdable_vars export pathABC="/home/alex/Documents/A/B/C"
然后你可以使用cd pathABC
(从这里 )
在终端中运行脚本时,将运行子进程。 在这个子程序中,即您的脚本将更改为指定的任何目录。 但是在父进程中,即运行脚本的位置仍处于旧路径中。 或者我们可以说:
The scope of cd command is only for child process not parent
你在思考错误。 当前shell保留在同一目录中时, 脚本已移至新目录。
您可以通过在新目录中创建另一个脚本并在更改目录后从脚本运行它来看到:
#!/bin/sh cd /home/alex/Documents/A/B/C && ./another_script.sh # (if it is executable)
第二个脚本将从新目录运行。
HelloWorld
只是脚本的输出。
因为hello world只是一个跟踪语句,让我们试试这个:
创建包含以下内容的bash脚本文件cd.sh
:
#!/bin/bash echo "/home/mike/Documents/A/B/C"
-
.sh
扩展名是一种较旧的约定,它将bash脚本文件名作为扩展名。 它纯粹是化妆品,通常是不必要的。 但是在这种情况下,区别于核心cd
命令很重要。
使用以下方法标记bash脚本文件
chmod a+x cd.sh
现在运行文件:
$ cd $(./cd.sh) bash: cd: /home/alex/Documents/A/B/C: No such file or directory
-
cd
我们都知道。 -
$(...)
在括号内执行命令并返回输出。 - 如果
cd.sh
在您的路径中,则无需指定它的位置。 我们以./
作为前缀,指定命令在当前目录中。 -
cd.sh
脚本的echo
输出通过$(...)
发送回父节点。 父(我们的shell提示符)使用此输出并将其传递给Linuxcd
命令。
正如其他人提到的那样,子进程无法更改父进程的目录。 这是孩子可以告诉父母在过程结束后去哪里的一种方式。