如何使 cd 命令在 bash 脚本子 shell 之外生效?

如何使 cd 命令在 bash 脚本子 shell 之外生效?

我做了这个脚本:

#!/bin/bash

if [[ $# -ne 1 ]]; then
  echo "only use one argument"
  exit 1
fi

mkdir $1
sleep 0.5
cd $1

exit 0

我想制作一个脚本,稍后将其放入 /usr/bin 中,这样每当我编写crdir asd它时,它都会创建目录并自动将当前目录更改为新目录。

这种方式行不通,因为schell脚本显然是一个子shell,而cd命令在子shell之外不会生效,那么我该怎么做呢?

我在网上读到我应该“获取”它,在前面运行一个点,比如. ./crdir asd,但首先,当我尝试这个时,ssh 与机器断开了连接,其次,这不会按照我想要的方式工作它作为命令来工作。

有小费吗?

编辑:我也尝试过,mkdir aaa; cd !#但它不起作用,它!#作为上一个命令的参数。

答案1

让它成为一个函数:

crdir() {
  if [ "$#" -eq 1 ]; then
    mkdir -p -- "$1" && cd -P -- "$1"
  else
    echo >&2 "Usage: crdir <directory-path>"
    return 1
  fi
}

您可以将其放入您的~/.bashrc.

您的. crdir方法也可以工作(在可以接受参数bash的 shell中.),但是您需要删除exit 0导致 shell 退出的方法。另请注意,当不在 POSIX 模式下时,bash如果在 中找不到要在当前目录中查找的文件,这使得它有点危险(与在 末尾$PATH添加或空条目相同的级别) 。.$PATH

另外,如果. crdir不带参数调用,则脚本将继承 shell 的位置参数。例如,set foo; . crdir不会返回错误并创建foo目录。

关于您的脚本的其他一些注释:

#!/bin/bash

请注意,当获取文件时,she-bang 将被忽略(仅视为注释)。

if [[ $# -ne 1 ]]; then
  echo "only use one argument"

最好在 stderr ( echo >&2 text) 上输出错误消息。

  exit 1
fi

mkdir $1

不加引号的参数扩展在 中具有特殊含义bash,您几乎不应该这样做。

另外,如果$1以 开头-,它将被视为一个选项mkdir。您需要使用--选项结束标记来告诉mkdir的内容$1不是选项,即使它以 开头-

您也没有检查mkdir命令是否成功。

您可能还想使用-p指示mkdir创建所有目录组件的选项,并且mkdir如果目录已存在则不会返回失败。所以:

 mkdir -p -- "$1" &&
sleep 0.5

无需睡觉。成功返回即可确定目录已经创建mkdir

cd $1

再说一遍,你已经得到了引用和-问题。此外,bash您需要-P选择以cd与其他实用程序(如mkdir.所以:

 cd -P -- "$1"

(暂时忽略名为-$CDPATH的路径,我希望您不要使用或仅使用理智的值)。

exit 0

再说一遍,您没有检查退出状态cd并返回成功退出状态,即使mkdircd失败。当脚本被获取时,它由源外壳解释,因此这exit将导致它退出。

在这里,我将脚本重写为:

if [ "$#" -eq 1 ]; then
  mkdir -p -- "$1" && cd -P -- "$1"
else
  ! echo >&2 "Usage: crdir  <directory-path>"
fi

答案2

一个函数怎么样:

crdir() { mkdir $1; cd $1; }

相关内容