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

这篇博客探讨了在shell脚本中使用'cd'命令为何无法改变当前终端目录的问题。博主分享了多种解决方案,包括使用source命令、定义bash函数、设置别名等方法,以确保脚本能够正确切换到目标目录。
摘要由CSDN通过智能技术生成

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

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

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


#1楼

在我的特殊情况下,我需要太多次才能更改同一目录。 因此,在我的.bashrc(我使用ubuntu)上,我添加了

1-

$ nano〜。/ bashrc

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

2

$ source〜/ .bashrc

3-

$ switchp java

直接可以执行:cd / home / tree / projects / java

希望有帮助!


#2楼

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

./<your file name>无效,因为它不会更改终端中的目录,而只会更改特定于该脚本的目录。

这是我的程序

#!/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$ 

#3楼

如果您将用作外壳,最好的解决方案是创建一个函数。 例如,给定原始问题,您可以复制下面的4行并将其粘贴到fish命令行中:

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

这将创建函数并保存以供以后使用。 如果您的项目发生更改,只需使用新路径重复该过程即可。

如果愿意,可以执行以下操作来手动添加功能文件:

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

并输入文字:

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

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

注意:使用funcsave的第一种方法将为您创建proj.fish文件。


#4楼

您可以使用运算符&&:

cd myDirectory && ls


#5楼

如果以反斜杠结束行,则可以在同一子Shell中执行一些行。

cd somedir; \
pwd

#6楼

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

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

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

move_me 

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


#7楼

我有一个名为p的简单bash脚本,用于管理目录更改
github.com/godzilla/bash-stuff
只需将脚本放入本地bin目录(/ usr / local / bin)
并把

alias p='. p'

在你的.bashrc中


#8楼

采购要运行的脚本是一种解决方案,但应注意,此脚本可以直接修改当前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目录书签。


#9楼

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

. script_name

或者,其更具可读性但特定于Shell的别名source

source script_name

这样可以避免使用subshel​​l,而是允许任何变量或内建函数(包括cd )影响当前的shell。


#10楼

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

./myscript.sh

. ./myscript.sh

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


#11楼

Shell脚本在一个子Shell中运行,每个子Shell对当前目录都有自己的概念。 cd成功,但是一旦子shell退出,您就回到了交互式shell中,那里什么也没有改变。

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

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

#12楼

你没做错什么! 您已经更改了目录,但仅在运行脚本的子外壳中进行了更改。

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

. proj

但是我更希望格雷格的建议在这种简单情况下使用别名。


#13楼

当您启动shell脚本时,它将运行该shell的实例( /bin/bash )。 因此,您的脚本仅启动外壳程序,更改目录并退出。 换句话说,shell脚本中的cd (和其他此类命令)不影响也不具有对其启动时所在的shell的访问权。


#14楼

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

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


#15楼

您可以执行以下操作:

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

编辑:这也可以被“点缀”,以防止后续壳的创建。

例:

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

#16楼

杰里米·鲁滕(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

#17楼

快速浏览目录,有$ 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楼

您可以结合使用别名和脚本,

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

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

例如,您的脚本可能是

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

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


#19楼

制作一个bash脚本,将其cd到选择目录:

创建脚本文件

#!/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即可。


#20楼

最后使用exec bash

bash脚本在其当前环境或其子级环境上运行,但绝不在其父级环境上运行。

但是,经常会问这个问题,因为一个人想另一个目录中执行 bash脚本留在某个目录中的(新)bash提示符下

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

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

#21楼

您可以在.bash_profile创建如下所示的函数,它将正常运行。

以下函数采用一个可选参数,该参数是一个项目。 例如,您可以运行

cdproj

要么

cdproj project_name

这是函数定义。

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

不要忘记来源您的.bash_profile


#22楼

您不需要脚本,只需设置正确的选项并创建环境变量。

shopt -s cdable_vars

您的~/.bashrc中的cd允许cd到环境变量的内容。

创建这样的环境变量:

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

您可以使用:

cd myjava

其他选择


#23楼

只需运行:

cd /home/xxx/yyy && command_you_want

#24楼

使用Bash配置文件功能:

bash配置文件的一个功能是存储自定义功能,这些功能可以在终端或bash脚本中运行,就像您运行应用程序/命令的方式一样,这也可以用作长命令的快捷方式。

为了使您的功能高效的系统广泛运行,您需要在几个文件的末尾复制功能

/home/user/.bashrc
/home/user/.bash_profile
/root/.bashrc
/root/.bash_profile

您可以sudo kwrite /home/user/.bashrc /home/user/.bash_profile /root/.bashrc /root/.bash_profile来快速编辑/创建这些文件

脚本示例

cdd制作cd ..快捷方式

cdd() {
  cd ..
}

ls捷径

ll() {
  ls -l -h
}

ls捷径

lll() {
  ls -l -h -a
}

如何 :

在文件末尾复制函数并重新启动终端,然后可以运行cdd或编写的任何函数


#25楼

这应该做您想要的。 转到感兴趣的目录(从脚本内),然后生成一个新的bash shell。

#!/bin/bash

# saved as mov_dir.sh
cd ~/mt/v3/rt_linux-rt-tools/
bash

如果运行此命令,它将带您到感兴趣的目录,并且在退出时将带您回到原始位置。

root@intel-corei7-64:~# ./mov_dir.sh

root@intel-corei7-64:~/mt/v3/rt_linux-rt-tools# exit
root@intel-corei7-64:~#

退出时,这甚至可以带您回到原始目录( CTRL + d


#26楼

注意讨论如何设置父进程的工作目录?

它包含一些令人毛骨悚然的答案,例如https://stackoverflow.com/a/2375174/755804 (通过gdb更改父进程目录,请不要这样做)和https://stackoverflow.com/a/51985735/755804 (该命令tailcdcd目录名注入父进程的输入流;嗯,理想情况下,它应该是bash的一部分,而不是hack)


#27楼

LOOOOOng时间过后,但我做了以下事情:

创建一个名为case的文件

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

#!/bin/sh

cd /home/"$1"

保存然后:

chmod +x case

我还在.bashrc创建了一个别名:

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

现在,当我键入:

case 12345

本质上我在输入:

cd /home/12345

您可以在“ case”之后输入任何文件夹:

case 12

case 15

case 17

就像输入:

cd /home/12

cd /home/15

cd /home/17

分别

在我的情况下,路径要长得多-这些家伙更早地用〜信息对其进行了总结。


#28楼

脚本中的cd从技术上来说可以正常运行,因为它更改了运行脚本的shell的目录,但这是与交互式shell分开的一个独立过程。

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

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

您可以只输入它或将其放在各种Shell启动文件之一中。


#29楼

您可以将Adam&Greg的别名和点方法结合起来,以制作出更具动态感的内容-

alias project=". project"

现在运行项目别名将在当前外壳程序(而不是子外壳程序)中执行项目脚本。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值