为什么“cd”不能在bash shell脚本中工作?

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

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

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

Shell脚本在子shell中运行,并且每个子shell都有自己的当前目录的概念。 cd成功了,但是一旦子shell退出,你就回到了交互式shell中,并且没有任何改变。

解决这个问题的一个方法是使用别名:

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

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

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

 . proj 

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

脚本中的cd在技​​术上起作用,因为它改变了运行脚本的shell的目录,但是这是一个与交互式shell分离的独立进程。

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

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

你可以直接input或者把它放在各种shell启动文件之一中。

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

 ./myscript.sh 

 . ./myscript.sh 

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

为了制作一个bash脚本,它将cd到一个select目录:

创build脚本文件

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

然后在启动文件中创build一个别名。

 #!/ bin / sh的
 #file /scripts/mastercode.sh
 #
别名cdjava ='。  /脚本/ cdjava”

  • 我创build了一个启动文件,在这里我转储所有的别名和自定义函数。
  • 然后我把这个文件放到我的.bashrc文件中,让它在每次启动时都设置好。

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

然后在.bashrc文件的末尾:

源/scripts/mastercode.sh


现在它很容易cd到您的java目录,只需键入cdjava,你在那里。

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

 CDPATH=:$HOME/projects 

领先的结肠是重要的; 这意味着如果在当前目录中有一个目录'dir',那么' cd dir '将会改变为' cd dir ',而不是跳到别的地方。 按照所示的值设置,你可以这样做:

 cd java 

如果在当前目录中没有名为java的子目录,那么它会直接把你带到$ HOME / projects / java – 没有别名,没有脚本,没有可疑的exec或dot命令。

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

我通过使用我的代码来工作. <your file name> . <your file name>

./<your file name>不起作用,因为它不会改变你在terminal中的目录,它只是改变特定于该脚本的目录。

这是我的程序

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

这是我的terminal

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

您可以使用

SCRIPT_NAME

执行它,它不会在子shell中执行。

当你启动一个shell脚本时,它会运行该shell的一个实例( /bin/bash )。 因此,你的脚本只是启动一个shell,改变目录并退出。 换句话说,在shell脚本中的cd (和其他这样的命令)不会影响也不能访问从其启动的shell。

在我的特殊情况下,我需要太多的时间来改变相同的目录。 所以在我的.bashrc(我使用Ubuntu的)我已经添加了

1 –

$ nano〜。/ bashrc

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

2-

$ source〜/ .bashrc

3 –

$ switchp java

直接它会做:cd / home / tree / projects / java

希望有所帮助!

简单地运行:

 cd /home/xxx/yyy && command_you_want 

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

您可能想要使用符号链接 。 它允许你创build一个文件或目录的“快捷方式”,所以你只需要input类似cd my-project东西。

你可以结合一个别名和一个脚本,

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

只要脚本回应目标path。 请注意,这些是围绕脚本名称的反引号。

例如,你的脚本可能是

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

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

最后使用exec bash

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

然而,这个问题经常被问到,因为在另一个目录执行一个bash脚本之后,一个想要留在某个目录中的bash提示符下。

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

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

你可以做以下事情:

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

编辑:这也可以是'虚线',以防止后续的shell的创build。

例:

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

你可以结合Adam&Greg的别名和dot方法来做出更dynamic的东西 –

 alias project=". project" 

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

您可以使用运算符&&:

cd myDirectory && ls

LOOOOOng时间后,但我做了以下几点:

创build一个名为case的文件

将以下内容粘贴到文件中:

 #!/bin/sh cd /home/"$1" 

保存它然后:

 chmod +x case 

我也在我的.bashrc创build了一个别名:

 alias disk='cd /home/; . case' 

现在当我input:

 case 12345 

基本上我在打字:

 cd /home/12345 

您可以在“大小写”之后键入任何文件夹:

 case 12 case 15 case 17 

这就像input:

 cd /home/12 cd /home/15 cd /home/17 

分别

就我而言,path要长得多 – 这些人早些时候总结了〜信息。

在find要运行的脚本是一个解决scheme的时候,应该知道这个脚本可以直接修改当前shell的环境。 也不可能再传递参数。

另一种方法是在bash中将脚本实现为一个函数。

 function cdbm() { cd whereever_you_want_to_go echo "Arguments to the functions were $1, $2, ..." } 

autojump使用以下技术: http ://github.com/joelthelion/autojump/wiki为您提供学习shell目录书签。

在〜/ .bash_profile文件中。 添加下一个function

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

重新启动terminal,您可以键入

 move_me 

并且您将被移动到目标文件夹。

你可以在你的.bash_profile创build一个像下面这样的函数,它可以顺利运行

下面的函数采用一个可选参数,特别是一个项目,例如,你可以运行

$cdproj

要么

$cdproj project_name

 function cdproj(){ dir=/Users/yourname/projects if [ $1 ]; then cd ${dir}/${1} else cd ${dir} fi } 

不要忘记来源.bash_profile

这里是我写的关于确切问题的博文:

http://blog.sampsonchen.com/2012/09/18/three-shortcuts-to-quickly-change-directories-in-linux/

另外还有一个叫做z的工具: https : //github.com/rupa/z

如果你用鱼为壳,最好的解决办法是创build一个函数。 举一个例子,给出原来的问题,你可以复制下面的4行并粘贴到你的鱼命令行:

 function proj cd /home/tree/projects/java end funcsave proj 

这将创build该function并保存以备后用。 如果您的项目更改,只需重新使用新path的过程。

如果您愿意,可以通过执行以下操作手动添加function文件:

 nano ~/.config/fish/functions/proj.fish 

并input文字:

 function proj cd /home/tree/projects/java end 

最后按ctrl + x退出,然后按回车保存更改。

注意:第一种使用funcsave的方法为你创buildproj.fish文件 )。

我有一个简单的名为P的bash脚本来pipe理目录更改
github.com/godzilla/bash-stuff
只需将脚本放在本地bin目录(/ usr / local / bin)
并放

 alias p='. p' 

在你的.bashrc中

您不需要脚本,只需设置正确的选项并创build一个环境variables。

 shopt -s cdable_vars 

~/.bashrc允许cd到环境variables的内容。

创build这样一个环境variables:

 export myjava="/home/tree/projects/java" 

你可以使用:

 cd myjava 

其他select 。

如果用反斜线结束行,可以在同一个子shell中执行一些行。

 cd somedir; \ pwd