从Bash脚本更改当前目录

时间:2022-09-12 23:24:33

Is it possible to change current directory from a script?

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

I want to create a utility for directory navigation in Bash. I have created a test script that looks like the following:

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

#!/bin/bash
cd /home/artemb

When I execute the script from the Bash shell the current directory doesn't change. Is it possible at all to change the current shell directory from a script?

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

13 个解决方案

#1


You need to convert your script to a shell function:

您需要将脚本转换为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
}

The reason is that each process has its own current directory, and when you execute a program from the shell it is run in a new process. The standard "cd", "pushd" and "popd" are builtin to the shell interpreter so that they affect the shell process.

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

By making your program a shell function, you are adding your own in-process command and then any directory change gets reflected in the shell process.

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

#2


When you start your script, a new process is created that only inherits your environment. When it ends, it ends. Your current environment stays as it is.

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

Instead, you can start your script like this:

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

. myscript.sh

The . will evaluate the script in the current environment, so it might be altered

这个。将评估当前环境中的脚本,因此可能会更改

#3


In light of the unreadability and overcomplication of answers, i believe this is what the requestor should do

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

  1. add that script to the PATH
  2. 将该脚本添加到PATH

  3. run the script as . scriptname
  4. 以脚本运行。脚本名

The . (dot) will make sure the script is not run in a child shell.

这个。 (点)将确保脚本不在子shell中运行。

#4


Putting the above together, you can make an alias

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

alias your_cmd=". your_cmd"

if you don't want to write the leading "." each time you want to source your script to the shell environment, or if you simply don't want to remember that must be done for the script to work correctly.

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

#5


If you are using bash you can try alias:

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

into the .bashrc file add this line:

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

alias p='cd /home/serdar/my_new_folder/path/'

when you write "p" on the command line, it will change the directory.

当您在命令行上写“p”时,它将更改目录。

#6


If you run a bash script then it will operates on its current environment or on those of its children, never on the parent.

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

If goal is to run your command : goto.sh /home/test Then work interactively in /home/test one way is to run a bash interactive subshell within your script :

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

#!/bin/bash
cd $1
exec bash

This way you will be in /home/test until you exit ( exit or Ctrl+C ) of this shell.

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

#7


With pushd the current directory is pushed on the directory stack and it is changed to the given directory, popd get the directory on top of the stack and changes then to it.

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

pushd ../new/dir > /dev/null
# do something in ../new/dir
popd > /dev/null

#8


Simply go to

简单地去吧

yourusername/.bashrc (or yourusername/.bash_profile on MAC) by an editor

and add this code next to the last line:

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

alias yourcommand="cd /the_path_you_wish"

Then quit editor.

然后退出编辑器。

Then type:

source ~/.bashrc or source ~/.bash_profile on MAC.

now you can use: yourcommand in terminal

现在您可以在终端中使用:yourcommand

#9


I've made a script to change directory. take a look: https://github.com/ygpark/dj

我已经制作了一个脚本来更改目录。看看:https://github.com/ygpark/dj

#10


Basically we use cd.. to come back from every directory. I thought to make it more easy by giving the number of directories with which you need to come back at a time. You can implement this using a separate script file using the alias command . For example:

基本上我们使用cd ..从每个目录返回。我想通过给出你需要一次回来的目录数量来让它变得更容易。您可以使用alias命令使用单独的脚本文件来实现此目的。例如:

code.sh

#!/bin/sh
 _backfunc(){
 if [ "$1" -eq 1 ]; then
  cd ..
 elif [ "$1" -eq 2 ]; then
  cd ../..
 elif [ "$1" -eq 3 ]; then
  cd ../../..
 elif [ "$1" -eq 4 ]; then
  cd ../../../..
 elif ["$1" -eq 10]; then
  cd /home/arun/Documents/work
 fi
 }
alias back='_backfunc'   

After using source code.sh in the current shell you can use :

在当前shell中使用源代码.sh后,您可以使用:

$back 2 

to come two steps back from the current directory. Explained in detail over here. It is also explained over there how to put the code in ~/.bashrc so that every new shell opened will automatically have this new alias command. You can add new command to go to specific directories by modifying the code by adding more if conditions and different arguments. You can also pull the code from git over here.

从当前目录返回两步。在这里详细解释。在那里还解释了如何将代码放在〜/ .bashrc中,以便每个打开的新shell都会自动拥有这个新的别名命令。您可以通过添加更多条件和不同参数来修改代码来添加新命令以转到特定目录。你也可以在这里从git中提取代码。

#11


This approach is easier for me.

这种方法对我来说更容易。

Suppose on a personal iMac where you are an admin, under the default directory when a command window is opened, /Users/jdoe, this will be the directory to go to: /Users/jdoe/Desktop/Mongo/db.3.2.1/bin.

假设在你是管理员的个人iMac上,在打开命令窗口的默认目录下,/ Users / jdoe,这将是要访问的目录:/Users/jdoe/Desktop/Mongo/db.3.2.1 /箱。

These are the steps that can have the job done:

这些是可以完成工作的步骤:

  1. vi mongobin, in which I entered: cd /Users/jdoe/Desktop/Mongo/db.3.2.1/bin as the first line.
  2. vi mongobin,我在其中输入:cd /Users/jdoe/Desktop/Mongo/db.3.2.1/bin作为第一行。

  3. chmod 755 mongobin
  4. chmod 755 mongobin

  5. source mongobin
  6. pwd

Voila!

#12


I've also created a utility called goat that you can use for easier navigation.

我还创建了一个名为goat的实用程序,您可以使用它来更轻松地导航。

You can view the source code on GitHub.

您可以在GitHub上查看源代码。

As of v2.3.1 the usage overview looks like this:

从v2.3.1开始,使用概述如下所示:

# Create a link (h4xdir) to a directory:
goat h4xdir ~/Documents/dev

# Follow a link to change a directory:
cd h4xdir

# Follow a link (and don't stop there!):
cd h4xdir/awesome-project

# Go up the filesystem tree with '...' (same as `cd ../../`):
cd ...

# List all your links:
goat list

# Delete a link (or more):
goat delete h4xdir lojban

# Delete all the links which point to directories with the given prefix:
goat deleteprefix $HOME/Documents

# Delete all saved links:
goat nuke

# Delete broken links:
goat fix

#13


I like to do the same thing for different projects without firing up a new shell.

我喜欢在不启动新shell的情况下为不同的项目做同样的事情。

In your case:

在你的情况下:

cd /home/artemb

Save the_script as:

将the_script保存为:

echo cd /home/artemb

Then fire it up with:

然后点开它:

\`./the_script\`

Then you get to the directory using the same shell.

然后使用相同的shell到达目录。

#1


You need to convert your script to a shell function:

您需要将脚本转换为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
}

The reason is that each process has its own current directory, and when you execute a program from the shell it is run in a new process. The standard "cd", "pushd" and "popd" are builtin to the shell interpreter so that they affect the shell process.

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

By making your program a shell function, you are adding your own in-process command and then any directory change gets reflected in the shell process.

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

#2


When you start your script, a new process is created that only inherits your environment. When it ends, it ends. Your current environment stays as it is.

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

Instead, you can start your script like this:

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

. myscript.sh

The . will evaluate the script in the current environment, so it might be altered

这个。将评估当前环境中的脚本,因此可能会更改

#3


In light of the unreadability and overcomplication of answers, i believe this is what the requestor should do

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

  1. add that script to the PATH
  2. 将该脚本添加到PATH

  3. run the script as . scriptname
  4. 以脚本运行。脚本名

The . (dot) will make sure the script is not run in a child shell.

这个。 (点)将确保脚本不在子shell中运行。

#4


Putting the above together, you can make an alias

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

alias your_cmd=". your_cmd"

if you don't want to write the leading "." each time you want to source your script to the shell environment, or if you simply don't want to remember that must be done for the script to work correctly.

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

#5


If you are using bash you can try alias:

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

into the .bashrc file add this line:

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

alias p='cd /home/serdar/my_new_folder/path/'

when you write "p" on the command line, it will change the directory.

当您在命令行上写“p”时,它将更改目录。

#6


If you run a bash script then it will operates on its current environment or on those of its children, never on the parent.

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

If goal is to run your command : goto.sh /home/test Then work interactively in /home/test one way is to run a bash interactive subshell within your script :

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

#!/bin/bash
cd $1
exec bash

This way you will be in /home/test until you exit ( exit or Ctrl+C ) of this shell.

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

#7


With pushd the current directory is pushed on the directory stack and it is changed to the given directory, popd get the directory on top of the stack and changes then to it.

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

pushd ../new/dir > /dev/null
# do something in ../new/dir
popd > /dev/null

#8


Simply go to

简单地去吧

yourusername/.bashrc (or yourusername/.bash_profile on MAC) by an editor

and add this code next to the last line:

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

alias yourcommand="cd /the_path_you_wish"

Then quit editor.

然后退出编辑器。

Then type:

source ~/.bashrc or source ~/.bash_profile on MAC.

now you can use: yourcommand in terminal

现在您可以在终端中使用:yourcommand

#9


I've made a script to change directory. take a look: https://github.com/ygpark/dj

我已经制作了一个脚本来更改目录。看看:https://github.com/ygpark/dj

#10


Basically we use cd.. to come back from every directory. I thought to make it more easy by giving the number of directories with which you need to come back at a time. You can implement this using a separate script file using the alias command . For example:

基本上我们使用cd ..从每个目录返回。我想通过给出你需要一次回来的目录数量来让它变得更容易。您可以使用alias命令使用单独的脚本文件来实现此目的。例如:

code.sh

#!/bin/sh
 _backfunc(){
 if [ "$1" -eq 1 ]; then
  cd ..
 elif [ "$1" -eq 2 ]; then
  cd ../..
 elif [ "$1" -eq 3 ]; then
  cd ../../..
 elif [ "$1" -eq 4 ]; then
  cd ../../../..
 elif ["$1" -eq 10]; then
  cd /home/arun/Documents/work
 fi
 }
alias back='_backfunc'   

After using source code.sh in the current shell you can use :

在当前shell中使用源代码.sh后,您可以使用:

$back 2 

to come two steps back from the current directory. Explained in detail over here. It is also explained over there how to put the code in ~/.bashrc so that every new shell opened will automatically have this new alias command. You can add new command to go to specific directories by modifying the code by adding more if conditions and different arguments. You can also pull the code from git over here.

从当前目录返回两步。在这里详细解释。在那里还解释了如何将代码放在〜/ .bashrc中,以便每个打开的新shell都会自动拥有这个新的别名命令。您可以通过添加更多条件和不同参数来修改代码来添加新命令以转到特定目录。你也可以在这里从git中提取代码。

#11


This approach is easier for me.

这种方法对我来说更容易。

Suppose on a personal iMac where you are an admin, under the default directory when a command window is opened, /Users/jdoe, this will be the directory to go to: /Users/jdoe/Desktop/Mongo/db.3.2.1/bin.

假设在你是管理员的个人iMac上,在打开命令窗口的默认目录下,/ Users / jdoe,这将是要访问的目录:/Users/jdoe/Desktop/Mongo/db.3.2.1 /箱。

These are the steps that can have the job done:

这些是可以完成工作的步骤:

  1. vi mongobin, in which I entered: cd /Users/jdoe/Desktop/Mongo/db.3.2.1/bin as the first line.
  2. vi mongobin,我在其中输入:cd /Users/jdoe/Desktop/Mongo/db.3.2.1/bin作为第一行。

  3. chmod 755 mongobin
  4. chmod 755 mongobin

  5. source mongobin
  6. pwd

Voila!

#12


I've also created a utility called goat that you can use for easier navigation.

我还创建了一个名为goat的实用程序,您可以使用它来更轻松地导航。

You can view the source code on GitHub.

您可以在GitHub上查看源代码。

As of v2.3.1 the usage overview looks like this:

从v2.3.1开始,使用概述如下所示:

# Create a link (h4xdir) to a directory:
goat h4xdir ~/Documents/dev

# Follow a link to change a directory:
cd h4xdir

# Follow a link (and don't stop there!):
cd h4xdir/awesome-project

# Go up the filesystem tree with '...' (same as `cd ../../`):
cd ...

# List all your links:
goat list

# Delete a link (or more):
goat delete h4xdir lojban

# Delete all the links which point to directories with the given prefix:
goat deleteprefix $HOME/Documents

# Delete all saved links:
goat nuke

# Delete broken links:
goat fix

#13


I like to do the same thing for different projects without firing up a new shell.

我喜欢在不启动新shell的情况下为不同的项目做同样的事情。

In your case:

在你的情况下:

cd /home/artemb

Save the_script as:

将the_script保存为:

echo cd /home/artemb

Then fire it up with:

然后点开它:

\`./the_script\`

Then you get to the directory using the same shell.

然后使用相同的shell到达目录。