function
我的文件中有一个.bashrc
。我知道它的作用,它增加了 X 多个目录cd
这里是:
up()
{
local d=""
limit=$1
for ((i=1 ; i <= limit ; i++))
do
d=$d/..
done
d=$(echo $d | sed 's/^\///')
if [ -z "$d" ]; then
d=..
fi
cd $d
}
但是你能帮我解释一下这三件事吗?
d=$d/..
sed 's/^\///'
d=..
为什么不这样做:
up()
{
limit=$1
for ((i=1 ; i <= limit ; i++))
do
cd ..
done
}
用法:
<<<>>>~$ up 3
<<<>>>/$
d=$d/..
添加/..
到d
变量的当前内容。d
开始是空的,然后第一次迭代成功/..
,第二次/../..
等等。sed 's/^\///'
删除第一个/
,因此/../..
变为../..
(这可以使用参数扩展来完成,d=${d#/}
)。d=..
仅在其条件的上下文中才有意义:这样可以确保,如果
d
此时为空,则转到父目录。(up
没有参数等同于cd ..
。)这种方法比迭代更好,
cd ..
因为它保留cd -
了一步返回上一个目录(从用户的角度来看)的能力。函数可以简化:
这假设我们至少要向上移动一级,并添加n - 1级,因此我们不需要删除前导
/
或检查空的$d
.使用 Athena
jot
(athena-jot
Debian 中的软件包):(基于glenn jackman建议的变体)。
d=$d/..
这将 var 的当前内容
d
与 连接起来/..
并将其分配回d
.最终结果是制作
d
一个重复的字符串,如/../../../..
.sed 's/^///'
/
从您发布的代码中提供的字符串d
(echo $d) 中删除前导。可能更好地编写
sed 's|^/||'
以避免反斜杠。另一种方法(更快更简单)是编写
d=${d#/}
.d=..
将字符串分配
..
给 vard
。这仅作为一种确保
d
至少有一个..
的方法才有意义,以防测试if [ -z "$d" ]; then
表明 vard
为空。这只会发生,因为 sed 命令正在从d
.如果不需要从 d 中删除字符,则不需要
sed
orif
。您问题中的代码将始终向上移动至少一个目录。
更好的
local d
足以确保变量为空,不需要其他任何东西。但是,local 仅适用于某些 shell,如 bash 或 dash。具体来说,
ksh
(asyash
) 没有local
命令。更便携的解决方案是:for((
语法不可移植。最好使用类似的东西:强大的。
如果赋予函数第一个参数的值可能是负数或文本,则该函数应该能够处理这些值。
首先,让我们将值限制为仅数字(我将使用
c
forcount
):然后将计数值限制为正值:
此函数将愉快地接受 0 或任何文本(没有错误):
echo \
测试功能后删除。