我发现自己重复了很多:
mkdir longtitleproject
cd longtitleproject
有没有一种方法可以在一行中完成而不重复目录名称?我在这里狂欢。
答案1
这就是您需要的单行线。不需要其他配置:
mkdir longtitleproject && cd $_
在 bash 中,变量$_
是提供给上一个命令的最后一个参数。在本例中,为您刚刚创建的目录的名称。正如中所解释的man bash
:
_ At shell startup, set to the absolute pathname used to invoke
the shell or shell script being executed as passed in the envi‐
ronment or argument list. Subsequently, expands to the last
argument to the previous command, after expansion. Also set to
the full pathname used to invoke each command executed and
placed in the environment exported to that command. When check‐
ing mail, this parameter holds the name of the mail file cur‐
rently being checked."$_" is the last argument of the previous command.
用于cd $_
检索上一个命令的最后一个参数,而不是cd !$
因为cd !$
给出上一个命令的最后一个参数在 shell 历史中:
cd ~/
mkdir folder && cd !$
你最终回到家(或〜/)
cd ~/
mkdir newfolder && cd $_
你最终会进入 home 下的新文件夹! (或 ~/newfolder )
答案2
没有内置命令,但您可以轻松编写一个调用mkdir
then的函数cd
:
mkcd () {
mkdir "$1"
cd "$1"
}
将此代码放入您的~/.bashrc
文件中(或者~/.kshrc
对于 ksh 用户,或者~/.zshrc
对于 zsh 用户)。它定义了一个名为 的函数mkcd
。"$1"
当您运行函数时,将被函数的参数替换。
这个简单的版本有几个缺陷:
- 您无法一次创建一系列子目录。修复:将
-p
选项传递给mkdir
. (这可能是理想的,也可能不是理想的,因为它增加了未检测到拼写错误的风险,例如,当您打算在现有的 . 中创建时,mkcd mydierctory/newsub
会很高兴地创建。)mydierctory
mydierctory/newsub
newsub
mydirectory
- 如果参数以
-
but 不只是开头-
,那么mkdir
andcd
会将其解释为一个选项。如果只是-
,那么cd
就会将其解释为意思$OLDPWD
。如果后面+
跟着 0 个或多个数字,那么cd
zsh 会将其解释为目录堆栈中的索引。通过--
在参数之前传递,您可以解决第一个问题,但不能解决其他两个问题。./
如果参数是相对路径,则可以通过在参数前面添加来解决所有这些问题。 mkdir
不遵循CDPATH
,但cd
遵循,因此如果您设置的CDPATH
值不以.
(公认的有点不寻常的配置)开头,那么cd
可能会将您带到与刚刚创建的目录不同的目录。./
在相对路径前面添加可以修复此问题(它会导致CDPATH
被忽略)。- 如果
mkdir
失败,它会尝试执行cd
.修复:用于&&
分隔两个命令。
还是相当简单的:
mkcd () {
case "$1" in /*) :;; *) set -- "./$1";; esac
mkdir -p "$1" && cd "$1"
}
此版本仍然有可能使cd
go 进入与mkdir
刚刚在一种边缘情况下创建的目录不同的目录:如果 的参数mkcd
包含..
并通过符号链接。例如,如果当前目录是/tmp/here
且mylink
是 的符号链接/somewhere/else
,则mkdir mylink/../foo
创建/somewhere/foo
whilecd mylink/../foo
更改为foo
(即/tmp/here/foo
)。在参数中查找符号链接是不够的,因为 shell 还会跟踪其当前目录中的符号链接,因此cd /tmp/mylink; mkdir ../foo; cd ../foo
不会更改为新目录 ( /somewhere/else/foo
) 而是更改为/tmp/foo
.解决此问题的方法是让cd
内置函数首先解析所有路径组件(使用if does not exist..
是没有意义的,因此永远不需要看到任何路径组件)。foo/..
foo
mkdir
..
我们来到了这个强大但有点血腥的版本:
mkcd () {
case "$1" in
*/..|*/../) cd -- "$1";; # that doesn't make any sense unless the directory already exists
/*/../*) (cd "${1%/../*}/.." && mkdir -p "./${1##*/../}") && cd -- "$1";;
/*) mkdir -p "$1" && cd "$1";;
*/../*) (cd "./${1%/../*}/.." && mkdir -p "./${1##*/../}") && cd "./$1";;
../*) (cd .. && mkdir -p "${1#.}") && cd "$1";;
*) mkdir -p "./$1" && cd "./$1";;
esac
}
(练习:为什么我在第一次调用时使用子 shell cd
?)
如果 mkdir 失败,我想确保不更改当前目录。如果 shell 无权更改到其当前目录,则使用 cd - 或 $OLDPWD 改回还不够。另外,调用 cd 会更新 OLDPWD,因此我们只想执行一次(或恢复 OLDPWD)。
还有一些不太专业的方法可以不必重新输入上一行中的单词:
- 键入
cd
,然后Esc .(或Alt+ .)插入上一个命令中的最后一个参数。 cd !$
cd
在上一个命令的最后一个参数上执行。- 按Up调出上一个命令行,然后编辑它以更改
mkdir
为cd
。
但请注意u+
自该版本以来,它在 ksh93 中不起作用,已修复于 93u+m/1.0.0-alpha+d1483150 2021-01-05
答案3
如果你使用 Oh My Zsh,有一个命令叫做拿正是这样做的。它看起来像这样。
take myfolder
其实这个是我偶然发现的。我刚刚看了,它列在这个作弊来自 Oh My Zsh GitHub wiki。这是一个非常有用的命令,而且显然很容易自己创建。
答案4
按照您对 shell 配置文件进行了哪些自定义以提高工作效率?,这就是我的做法:
# make a directory and cd to it
mcd()
{
test -d "$1" || mkdir "$1" && cd "$1"
}
这意味着如果目录已经存在它也可以工作。