从Bash脚本更改当前目录

art*_*emb 175 bash environment

是否可以从脚本更改当前目录?

我想在Bash中为目录导航创建一个实用程序.我创建了一个如下所示的测试脚本:

#!/bin/bash
cd /home/artemb
Run Code Online (Sandbox Code Playgroud)

当我从Bash shell执行脚本时,当前目录不会更改.是否可以从脚本中更改当前的shell目录?

Nor*_*rtl 203

启动脚本时,会创建一个仅继承环境的新进程.当它结束时,它结束.您当前的环境保持不变.

相反,您可以像这样启动脚本:

. myscript.sh
Run Code Online (Sandbox Code Playgroud)

.将评估在当前环境中的脚本,所以它可能被改变

  • @lhunath为什么.sh扩展完全是eww? (10认同)
  • +1因为你是对的.虽然我真诚地怀疑他每次需要时都会想要更改目录.而且,`.sh`扩展名完全是eww.不要使用它们. (3认同)
  • 是的,通常最好不要那样使用它。大多数时候,您很高兴您当前的环境没有受到影响。但是后来我有脚本来为我做一些设置任务,包括更改到正确的位置,然后我 . 他们也是。顺便提一句。.sh 当然是个人风格的问题。在系统范围内安装脚本时,我可能不会使用它。但是在我的 ~/bin 中,我使用它们来知道什么是:) (3认同)
  • 对我来说,那篇文章中的推理是虚假的。结果似乎已经提前知道了,但要找到原因并不容易。所以我坚持我的观点,这是个人风格的问题,没有别的。 (3认同)

小智 164

您需要将脚本转换为shell函数:

#!/bin/bash
#
# this script should not be run directly,
# instead you need to source it from your .bashrc,
# by adding this line:
#   . ~/bin/myprog.sh
#

function myprog() {
  A=$1
  B=$2
  echo "aaa ${A} bbb ${B} ccc"
  cd /proc
}
Run Code Online (Sandbox Code Playgroud)

原因是每个进程都有自己的当前目录,当您从shell执行程序时,它将在新进程中运行.标准的"cd","pushd"和"popd"内置于shell解释器,因此它们会影响shell进程.

通过使程序成为shell函数,您将添加自己的进程内命令,然后任何目录更改都会反映在shell进程中.

  • +1.我注意到的一件事是在文件中,我们必须在调用之前定义函数.它可能会帮助像我一样缺乏经验的人. (4认同)
  • 你会如何在tcsh中做到这一点? (2认同)
  • 创建此 myprog.sh 文件并将其添加到 .bashrc 后,如何运行该脚本?我应该从另一个 shell 文件还是直接从 shell 调用我的函数?似乎这两种方式都不起作用...... (2认同)
  • @winden,请避免教授“function”关键字,并且*特别是*在名称后面将“function”与“()”组合起来。`function myfunc {` 是 bash 为向后兼容而实现的遗留 ksh 语法;`myfunc() {` 是现代 POSIX 语法,所有符合标准的 shell 都需要支持;`function myfunc() {` 以与**旧版 ksh​​ 和现代 POSIX sh 不兼容的方式合并两者。请参阅 https://wiki.bash-hackers.org/scripting/obsolete (2认同)

小智 53

鉴于答案的不可读性和过度复杂性,我相信这是请求者应该做的事情

  1. 将该脚本添加到 PATH
  2. 以脚本运行 . scriptname

.(点)将确保该脚本没有在子shell中运行.


小智 38

将上述内容放在一起,您可以创建一个别名

alias your_cmd=". your_cmd"
Run Code Online (Sandbox Code Playgroud)

如果你不想写领先的"." 每次要将脚本源代码发送到shell环境时,或者只是不想记住必须完成脚本才能正常工作.


aka*_*rca 31

如果您使用bash,可以尝试别名:

进入.bashrc文件添加以下行:

alias p='cd /home/serdar/my_new_folder/path/'
Run Code Online (Sandbox Code Playgroud)

当您在命令行上写"p"时,它将更改目录.

  • +1 为别名。shell 函数很有趣,但 OP 要求使用 cd 进行简单的导航。我猜大多数人都需要这样的脚本来导航源代码分支,对于该别名就足够了 (2认同)

phi*_*rdy 16

如果您运行bash脚本,那么它将在其当前环境或其子环境上运行,而不是在父环境中运行.

如果目标是运行您的命令:goto.sh/home/test然后在/ home/test中以交互方式工作,一种方法是在脚本中运行bash交互式子shell:

#!/bin/bash
cd $1
exec bash
Run Code Online (Sandbox Code Playgroud)

这样你将进入/ home/test,直到你退出(退出或Ctrl + C)这个shell.


seb*_*seb 13

使用pushd,当前目录被推送到目录堆栈并且它被更改为给定目录,popd获取堆栈顶部的目录然后更改为它.

pushd ../new/dir > /dev/null
# do something in ../new/dir
popd > /dev/null
Run Code Online (Sandbox Code Playgroud)

  • 这回答了我的问题 - 在S3 init脚本中积极部署此解决方案,它运行良好.谢谢@seb. (2认同)

小智 6

在 shell 脚本中添加以下 cd 行:

exec $SHELL
Run Code Online (Sandbox Code Playgroud)


Tha*_*gTD 5

只需转到

yourusername/.bashrc (or yourusername/.bash_profile on MAC) by an editor
Run Code Online (Sandbox Code Playgroud)

并将此代码添加到最后一行旁边:

alias yourcommand="cd /the_path_you_wish"
Run Code Online (Sandbox Code Playgroud)

然后退出编辑器。

然后输入:

source ~/.bashrc or source ~/.bash_profile on MAC.
Run Code Online (Sandbox Code Playgroud)

现在您可以使用:的终端命令