当前位置:  开发笔记 > 编程语言 > 正文

为什么"cd"不能在shell脚本中工作?

如何解决《为什么"cd"不能在shell脚本中工作?》经验,为你挑选了18个好方法。

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

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

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



1> Greg Hewgill..:

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

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

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


别名在〜/ .bash_profile和/或〜/ .bashrc中
乔纳森:虽然这是真的,但这与问题无关.如果必须每个列出MS-DOS中相应的缺陷,SO上的答案会得到两倍的时间!
解决它的另一种方法是获取脚本文件:`.my-script`或`source my-script`.
函数比别名更灵活,因此当别名不够时,您可以在下一步查看.
别名管理或更改的灵活性不高.如果有很多'cd',脚本可能会更好.
值得注意的是,在MS-DOS上,脚本的行为是被调用的脚本可以更改调用命令shell的目录(甚至是驱动器)吗?那个Unix没有这个缺陷?
s /缺陷/副作用/; s /值得注意/不&/
@ FedericoA.Ramponi或〜/ .bash_aliases

2> Adam Liss..:

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

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

. proj

但是我更喜欢Greg建议在这个简单的例子中使用别名.


`.`也拼写为`source`,选择你觉得更难忘的.
@Ephemient:好点源解释为什么它的工作源也证明了懒惰 - 不是必需品 - 往往是发明源的母亲
@ephemient:注意源是在C shell和Bash中使用的; 它在POSIX或Korn shell中不受支持,在经典的Bourne shell中也不受支持.
"source"用于Z-shell

3> DigitalRoss..:

cd脚本中的技术工作,因为它改变了运行脚本的外壳的目录,但是这是从你的交互shell分叉一个单独的进程.

与Posix兼容的解决此问题的方法是定义shell过程而不是shell调用的命令脚本.

jhome () {
  cd /home/tree/projects/java
}

您可以在其中输入或将其放入各种shell启动文件中.


我同意,这是最好的答案,碰到了.此外,别名在某些情况下可能是合适的,但如果他试图在脚本中使用cd并想要向其添加任何其他内容,则别名将毫无用处.
这看起来像一个解决方案!而我正在尝试实现它,但它没有执行:(这是我的脚本:#!/ bin/bash jhome(){echo"please"cd/home echo"work"} jhome
你也可以使用一个参数(或两个......),即:`jhome(){cd/home/tree/projects/$ 1; }`

4> 小智..:

cd是在脚本的shell中完成的.当脚本结束时,该shell退出,然后您将保留在您所在的目录中."源"脚本,不要运行它.代替:

./myscript.sh

. ./myscript.sh

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


这很酷,可能很有用.后者究竟做了什么(它是如何工作的)?这可能是此主题的最佳解决方案.
fwiw,在Adam Liss回答的评论部分,ephemient回答了'.'的问题.是.它与`source`是一回事

5> 小智..:

要创建一个将cd到选择目录的bash脚本:

创建脚本文件

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

然后在启动文件中创建别名.

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

我创建了一个启动文件,我将转储所有别名和自定义函数.

然后我将此文件发送到我的.bashrc中,以便在每次启动时设置它.

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

然后在.bashrc文件的末尾:

source /scripts/mastercode.sh



现在很容易cd到你的java目录,只需输入cdjava就可以了.


文件`mastercode.sh`不需要shabang(`#!/ bin/sh`),因为它不是(也不能)在子shell中执行.但与此同时,您需要记录此文件的shell"风味"; 例如,ksh或bash(或(t)csh/zsh等),它几乎肯定不是"sh".我通常会添加评论(但不是shebang)来传达此信息; 例如,_"这个文件应该来源(来自bash),而不是作为shell脚本运行."_

6> 小智..:

您可以使用.在当前shell环境中执行脚本:

. script_name

或者,它更具可读性但特定于shell的别名source:

source script_name

这避免了子shell,并允许任何变量或内置(包括cd)来影响当前的shell.



7> Jonathan Lef..:

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

CDPATH=:$HOME/projects

前导结肠很重要; 这意味着如果当前目录中有一个目录'dir',那么' cd dir'将更改为该目录,而不是在其他地方跳转.如图所示设置值,您可以:

cd java

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

我的$ 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



8> 小智..:

我通过使用我的代码工作.

./ 不起作用,因为它不会改变终端中的目录,只是更改特定于该脚本的目录.

这是我的计划

#!/bin/bash 
echo "Taking you to eclipse's workspace."
cd /Developer/Java/workspace

这是我的终端

nova:~ Kael$ 
nova:~ Kael$ . workspace.sh
Taking you to eclipe's workspace.
nova:workspace Kael$ 


`之间有什么区别?某事`和`./ something` ?? 这个答案对我有用,我不明白为什么.

9> Serge Stroob..:
使用exec bash

bash脚本在其当前环境或其子环境上运行,但从不在其父环境中运行.

但是,这个问题经常被问到,因为在从另一个目录执行bash脚本之后,想要在某个目录中保留bash提示符.

如果是这种情况,只需在脚本末尾执行子bash实例:

#!/usr/bin/env bash
cd /home/tree/projects/java
exec bash


这将创建一个新的子shell.当您键入`exit`时,您将返回运行此脚本的shell.

10> warhansen..:

只需运行:

cd /home/xxx/yyy && command_you_want



11> Daniel Spiew..:

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



12> workdreamer..:

在我的特定情况下,我需要太多次来更改同一目录.所以在我的.bashrc(我使用ubuntu)我添加了

1 -

$ nano~./bashrc

 function switchp
 {
    cd /home/tree/projects/$1
 }

2-

$ source~/.bashrc

3 -

$ switchp java

它会直接执行:cd/home/tree/projects/java

希望有所帮助!



13> Thevs..:

你可以这样做:

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

编辑:这也可以"点缀",以防止后续shell的创建.

例:

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


exec只替换运行cd命令的子shell,而不是运行脚本的shell.如果你点缀了剧本,那你就是对的.
呵呵,我觉得最好只用cd命令'点'单行脚本:)我还是会保留我的答案......这对于错误的愚蠢问题是正确的愚蠢答案:)

14> Jeremy Ruten..:

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

您可能希望使用符号链接.它允许您创建文件或目录的"快捷方式",因此您只需输入类似的内容cd my-project.



15> J. A. Faucet..:

您可以组合别名和脚本,

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

只要脚本回显目标路径.请注意,这些是围绕脚本名称的反引号. 

例如,您的脚本可能是

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

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


为什么?你可以使用:`proj(){cd"/ home/user/projects/java/$ 1"; }`=>`proj"foo"`(或者,'proj"foo bar"`<=如果你有空格)......或者甚至(例如):`proj(){cd"/ home/user /项目/ JAVA/$ 1" ; 转移; 为d; 做cd"$ d"; 完成; }`=>`proj abc` =>将`cd`变成`/ home/user/projects/java/a/b/c`

16> robertmoggac..:

您可以结合使用Adam&Greg的别名和点式方法来制作更具动感的内容 -

alias project=". project"

现在运行项目别名将在当前shell中执行项目脚本而不是子shell.



17> Gene T..:

快速导航目录,有$ CDPATH,cdargs和自动生成别名的方法

http://jackndempsey.blogspot.com/2008/07/cdargs.html

http://muness.blogspot.com/2008/06/lazy-bash-cd-aliaes.html

https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-5827311.html



18> mihai.ciorob..:

在您的〜/ .bash_profile文件中。添加下一个功能

move_me() {
    cd ~/path/to/dest
}

重新启动终端,您可以键入

move_me 

然后您将被移至目标文件夹。

推荐阅读
勤奋的瞌睡猪_715
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有