Linux 为什么“cd”在 shell 脚本中不起作用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/255414/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 16:40:55  来源:igfitidea点击:

Why doesn't "cd" work in a shell script?

linuxshell

提问by ashokgelal

I'm trying to write a small script to change the current directory to my project directory:

我正在尝试编写一个小脚本来将当前目录更改为我的项目目录:

#!/bin/bash
cd /home/tree/projects/java

I saved this file as proj, added execute permission with chmod, and copied it to /usr/bin. When I call it by: proj, it does nothing. What am I doing wrong?

我将此文件保存为 proj,添加了执行权限chmod,并将其复制到/usr/bin. 当我通过: 调用它时 proj,它什么也不做。我究竟做错了什么?

采纳答案by Greg Hewgill

Shell scripts are run inside a subshell, and each subshell has its own concept of what the current directory is. The cdsucceeds, but as soon as the subshell exits, you're back in the interactive shell and nothing ever changed there.

Shell 脚本在子shell 中运行,每个子shell 都有自己的当前目录的概念。的cd成功,但只要子shell退出,你是在交互式背壳和从来都没有改变,因此。

One way to get around this is to use an alias instead:

解决此问题的一种方法是改用别名:

alias proj="cd /home/tree/projects/java"

回答by Adam Liss

You're doing nothing wrong! You've changed the directory, but only within the subshell that runs the script.

你没有做错任何事!您已更改目录,但仅在运行脚本的子shell 中。

You can run the script in your current process with the "dot" command:

您可以使用“dot”命令在当前进程中运行脚本:

. proj

But I'd prefer Greg's suggestion to use an alias in this simple case.

但我更喜欢 Greg 的建议,在这种简单的情况下使用别名。

回答by Daniel Spiewak

When you fire a shell script, it runs a newinstance of that shell (/bin/bash). Thus, your script just fires up a shell, changes the directory and exits. Put another way, cd(and other such commands) within a shell script do not affect nor have access to the shell from which they were launched.

当您触发 shell 脚本时,它会运行该 shell 的一个实例 ( /bin/bash)。因此,您的脚本只是启动一个 shell,更改目录并退出。换句话说,cdshell 脚本中的(和其他此类命令)不会影响或访问启动它们的 shell。

回答by Jeremy Ruten

It only changes the directory for the script itself, while your current directory stays the same.

它只更改脚本本身的目录,而您当前的目录保持不变。

You might want to use a symbolic linkinstead. It allows you to make a "shortcut" to a file or directory, so you'd only have to type something like cd my-project.

您可能想改用符号链接。它允许您创建文件或目录的“快捷方式”,因此您只需键入类似cd my-project.

回答by Thevs

You can do following:

您可以执行以下操作:

#!/bin/bash
cd /your/project/directory
# start another shell and replacing the current
exec /bin/bash

EDIT: This could be 'dotted' as well, to prevent creation of subsequent shells.

编辑:这也可以“加点”,以防止创建后续外壳。

Example:

例子:

. ./previous_script  (with or without the first line)

回答by Jonathan Leffler

Jeremy Ruten's idea of using a symlink triggered a thought that hasn't crossed any other answer. Use:

Jeremy Ruten 使用符号链接的想法引发了一个没有跨越任何其他答案的想法。用:

CDPATH=:$HOME/projects

The leading colon is important; it means that if there is a directory 'dir' in the current directory, then 'cd dir' will change to that, rather than hopping off somewhere else. With the value set as shown, you can do:

领先的冒号很重要;这意味着如果当前目录中有一个目录 'dir',那么 ' cd dir' 将更改为该目录,而不是跳到其他地方。设置如图所示的值后,您可以执行以下操作:

cd java

and, if there is no sub-directory called java in the current directory, then it will take you directly to $HOME/projects/java - no aliases, no scripts, no dubious execs or dot commands.

并且,如果当前目录中没有名为 java 的子目录,那么它将直接带您到 $HOME/projects/java - 没有别名,没有脚本,没有可疑的 execs 或 dot 命令。

My $HOME is /Users/jleffler; my $CDPATH is:

我的 $HOME 是 /Users/jleffler;我的 $CDPATH 是:

:/Users/jleffler:/Users/jleffler/mail:/Users/jleffler/src:/Users/jleffler/src/perl:/Users/jleffler/src/sqltools:/Users/jleffler/lib:/Users/jleffler/doc:/Users/jleffler/work

回答by J. A. Faucett

You can combine an alias and a script,

您可以组合别名和脚本,

alias proj="cd \`/usr/bin/proj !*\`"

provided that the script echos the destination path. Note that those are backticks surrounding the script name. 

前提是脚本回显了目标路径。请注意,这些是围绕脚本名称的反引号。 

For example, your script could be

例如,您的脚本可能是

#!/bin/bash
echo /home/askgelal/projects/java/

The advantage with this technique is that the script could take any number of command line parameters and emit different destinations calculated by possibly complex logic.

这种技术的优点是脚本可以采用任意数量的命令行参数并发出由可能复杂的逻辑计算出的不同目的地。

回答by Tzachi.e

The cdis done within the script's shell. When the script ends, that shell exits, and then you are left in the directory you were. "Source" the script, don't run it. Instead of:

cd是在脚本的 shell 中完成的。当脚本结束时,该 shell 退出,然后您将留在原来的目录中。“源”脚本,不要运行它。代替:

./myscript.sh

do

. ./myscript.sh

(Notice the dot and space before the script name.)

(注意脚本名称前的点和空格。)

回答by Matt Thomas

To make a bash script that will cd to a select directory :

要制作一个将 cd 到选定目录的 bash 脚本:

Create the script file

创建脚本文件

#!/bin/sh
# file : /scripts/cdjava
#
cd /home/askgelal/projects/java

Then create an alias in your startup file.

然后在您的启动文件中创建一个别名。

#!/bin/sh
# file /scripts/mastercode.sh
#
alias cdjava='. /scripts/cdjava'


  • I created a startup file where I dump all my aliases and custom functions.
  • Then I source this file into my .bashrc to have it set on each boot.
  • 我创建了一个启动文件,在其中转储了所有别名和自定义函数。
  • 然后我将此文件输入到我的 .bashrc 中,以便在每次启动时设置它。

For example, create a master aliases/functions file: /scripts/mastercode.sh
(Put the alias in this file.)

例如,创建一个主别名/函数文件:/scripts/mastercode.sh
(将别名放在此文件中。)

Then at the end of your .bashrcfile:

然后在.bashrc文件的末尾:

source /scripts/mastercode.sh





Now its easy to cd to your java directory, just type cdjava and you are there.

现在很容易 cd 到您的 java 目录,只需键入 cdjava 即可。