我如何创建自己的“shell 命令”(例如 mkdir/cd 组合)?

我如何创建自己的“shell 命令”(例如 mkdir/cd 组合)?

我已经数不清有多少次希望有一个命令既能创建目录又能移动到该目录。基本上,我希望得到以下等价的命令:

mkdir -p /arbitrarily/long/path; cd /arbitrarily/long/path

但只需输入/arbitrarily/long/path一次,例如:

mk-cd /arbitrarily/long/path

我尝试创建一个脚本来执行此操作,但它只会更改脚本内的目录。我希望 shell 中的目录也发生更改。

#!/bin/bash
mkdir $1
cd $1
export PWD=$PWD

我怎样才能让它发挥作用?

答案1

最简单的方法是使用 shell 函数:

mkcd() {
    mkdir -p -- "$1" && cd -- "$1"
}

将其放置在您的.bashrc文件中,使其像其他 shell 命令一样可供您使用。

它不能作为外部脚本工作的原因是它cd改变了正在运行的脚本的当前目录,但不影响调用脚本的目录。这是设计使然!每个进程都有自己的工作目录,并由其子进程继承,但相反的情况则不可能。

除非是管道的一部分、在后台运行或明确在子 shell 中运行,否则 shell 函数不会在单独的进程中运行,而是在同一个进程中运行,就像命令已被调用一样。然后可以通过函数更改当前目录 shell。

这里使用&&来分隔两个命令,意思是如果第一个命令成功 ( mkdir),则运行第二个命令 ( cd)。因此,如果mkdir无法创建请求的目录,则尝试进入该目录是没有意义的。将打印一条错误消息,mkdir仅此而已。

-p使用的选项是mkdir告诉此实用程序创建任何缺失的目录,该目录是作为参数传递的目录名的完整路径的一部分。一个副作用是,如果您要求创建一个已经存在的目录,该mkcd函数不会失败,您将最终进入该目录。这可能被视为一个问题或一个功能。在前一种情况下,可以修改该函数,例如,只需向用户发出警告:

mkcd() {
    if [ -d "$1" ]; then
        printf "mkcd: warning, \"%s\" already exists\n" "$1"
    else
        mkdir -p "$1" 
    fi && cd "$1"
}

如果没有这个-p选项,初始函数的行为将会非常不同。

如果包含要创建的目录的目录尚不存在,mkdir则该函数也会失败。

如果要创建的目录已经存在,mkdir也会失败并且cd不会被调用。

最后,请注意设置/导出PWD是没有意义的,因为 shell 已经在内部执行了此操作。

编辑:我--向两个命令都添加了选项,以使目录名能够以破折号开头。

答案2

我想添加一个替代解决方案。

你的脚本将要如果使用.source命令调用它,则可以工作:

. mk-cd /arbitrarily/long/path

如果这样做,export脚本中的 就没有必要了。您可以.使用 来绕过输入alias

alias mk-cd='. mk-cd'

这种方法之所以有效,是因为脚本通常在子 shell 中运行,因此其环境在完成时会丢失,但.(或source)命令强制它在当前 shell 中运行。

这种技术对于那些对于功能来说过于复杂或正在开发且经常编辑的命令序列很有用:一旦输入alias.bash_aliases您就可以随意编辑脚本而无需重新初始化。

请注意以下几点:-

如果你编写了一个脚本必须.可以通过/命令调用source,有两种方法可以确保这一点:-

  1. .由于某种原因,使用/调用的脚本source不需要是可执行的,因此只需删除此权限,该脚本将不会在“$PATH”中找到,或者在使用明确路径调用时会出现权限错误。

  2. 或者,可以在脚本的开头使用以下技巧:

bind |& read && { echo 'Must be run from "." or "source" command'; exit 1; }

这是因为在子 shell 中bind发出了警告,尽管没有错误状态:因此read用于在没有输入时给出错误。

答案3

不是单个命令,但您不必重新输入只需使用的所有路径!$(这是 shell 历史记录中上一个命令的最后一个参数)。

例子:

mkdir -p /arbitrarily/long/path
cd !$

答案4

除了已经建议的内容之外,我还想推荐他妈的。这是一个通过修复错误来简化 shell 进程的 Python 框架。灵感来自这条推文,您只需输入配置的别名(默认情况下fuck),它就会尝试更正您的上一个命令。它的一个更正行为如下:

/etc $ cd somedir
bash: cd: No such file or directory
/etc $ fuck
mkdir somedir && cd somedir
/etc/somedir $ 

相关内容