我遇到了一个很酷的方式通过向 .bashrc 文件添加函数来向上移动超过 1 个目录级别。
只需打开 .bashrc 文件并插入函数即可完成:
#user defined functions
function cd_up() {
cd $(printf "%0.s../" $(seq 1 $1 ));
}
alias 'cd..'='cd_up'
我想了解如何阅读它。
它是用什么语言写的?
答案1
的内容.bashrc
由 Bash 本身执行,就像它执行脚本一样,或者实际上是交互式 shell 的执行方式。它是 POSIX shell 语言的一个变体,具有许多扩展(一些扩展是从其他 shell 借用的,主要是 Ksh,一些是 Bash 本身创建的)。
这里,function cd_up() { ... ; }
定义了一个函数。其标准形式只是cd_up() { ... ; }
,没有function
关键字。这$(...)
是一个命令替换,它在内部运行命令,并将其输出作为命令行参数。
这printf "%0.s../"
就是这里的技巧。printf
接受一个格式字符串(类似于 C 函数)printf()
,以及使用该格式字符串进行打印的多个参数。重要的是,它还会根据需要多次重复格式字符串以使用所有参数(C 函数没有也不能这样做)。说明符%0.s
告诉将参数打印为宽度为零的字符串,因此实际上,参数是不是打印。
但不变的部分../
是为每个参数打印一次,这意味着printf "%0.s../" a b
将打印两次,等等,这$(seq 1 $1)
是另一个命令替换,并且由于seq
打印数字列表,因此它用于向 提供所需数量的参数printf
。$1
是当前函数的第一个参数cd_up
。
因此,例如cd_up 2
,首先运行seq 1 2
,打印1 2
。它作为参数传递给printf
,因此您可以得到printf "%0.s../" 1 2
which prints ../../
。它被传递到cd
并cd ../../
运行,在目录树中向上两层。
使用set -x
,您可以看到 shell 实际运行的命令。 Bash 甚至用以下符号指示嵌套级别+
:
/tmp/foo$ set -x
/tmp/foo$ cd_up 2
+ cd_up 2
+++ seq 1 2
++ printf %0.s../ 1 2
+ cd ../../
/$
请注意,这并不重要什么的输出seq
是,只是其中有正确的单词数。由于命令替换未加引号,因此输出将通过分词,这意味着它在空格上分割为多个参数。printf "%0.s../" "$(seq 1 $1)"
总是在格式字符串之后只传递一个参数。 (请参阅链接页面上的示例。)
编写类似函数的另一种方法是使用简单的循环,但需要较少的技巧。几乎在 POSIX sh 中(local
不是 POSIX):
cd_up() {
local i=$1
while [ "$i" -gt 0 ]; do
cd ..
i=$((i - 1))
done
}
或者在 Bash/Zsh 中,使用算术 for 循环:
cd_up() {
local i
for (( i=$1; i > 0; i-- )); do
cd ..
done
}
尽管 的版本printf
更好,因为它只运行cd
一次,所以cd -
返回到原始目录,而不是中间目录。 (解决这个问题留作练习。)
有关 shell 语言的资源,请参见例如
答案2
bashrc 是一个 bash 脚本,每当 bash 以交互方式启动时都会运行。