为什么“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)
快速导航目录,还有$ 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
你可以结合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