我如何使用类似于 的东西cd -
,转到历史记录中的上一个目录,以便在目录历史记录中进一步回溯?例如,假设我的历史记录是:(1 为当前。)
- ~/
- ~/其他目录
- ~/真的/长/目录/名称/我/不想/再次/输入/但/不要/使用/足够/制作/一个/别名/
在这里使用cd -
会将我带到~/otherDirectory
#2,如果我再次使用它,它会将我带回到~/
#1(我不想进入)而不是非常长的目录 #3(我确实想进入)。总之,我如何进一步导航回目录历史记录?我可以编写一些 bash 来添加此功能吗?
我正在尝试返回目录历史记录(不止一个目录),就像使用向上箭头返回命令历史记录一样。希望这能说明这个问题之前没有被问过。
答案1
Bash 中的目录堆栈
在 Bash 中有一个东西叫做目录堆栈DIRSTACK
。堆栈是计算机科学中的一个基本数据结构,你可以在其中将元素堆叠在一起(就像书堆一样),但只能访问最近的一个(顶部)。
这是一个小演示 - 每次我将某些内容推送到目录堆栈时,我当前的工作目录都会设置为该项目;每次我弹出时 - 我们从堆栈中删除顶部(最左边)的项目,然后返回到下一个可用项目:
$> # pushd navigates to and stores the directory given
$> pwd
/home/xieerqi
$> pushd bin
~/bin ~
$> pushd /etc
/etc ~/bin ~
$> # popd deletes leftmost item, returns to next directory on left$> pwd
/etc
$> popd
~/bin ~
$> pwd
/home/xieerqi/bin
$>
最新的项目始终存储在堆栈顶部,即使您使用cd
$> dirs
/ /etc ~
$> cd /var
$> dirs
/var /etc ~
$>
该dirs
命令允许我们从堆栈中检索第 n 个元素。使用该输出作为参数,cd
我们可以导航到堆栈上的任何目录,而不会影响堆栈本身。请注意,即使我更改了当前工作目录(以及顶部元素),/etc/
和~
(堆栈元素 1 和 2)仍然保持不变
$> dirs
/var /etc ~
$> dirs +1
/etc
$> cd $(dirs +1)
$> pwd
/etc
$> dirs
/etc /etc ~
使用 DIRSTACK 行为模拟 Web 浏览器行为
您知道在网络浏览器中如果从 URL A 跳转到 URL B 和 URL C,您可以使用后退和前进箭头键在它们之间来回切换吗?
好吧,我们可以用这两个函数在 bash 中做同样的事情:
cd()
{
if [ $# -eq 0 ]; then
pushd "$HOME" > /dev/null
else
pushd "$@" > /dev/null
fi
}
cdback()
{
popd > /dev/null
printf "Returned to:%s\n" "$( dirs +0)"
}
函数优先于别名,因此我们可以利用这一点,对给定的每个参数进行调用cd
(pushd
如果没有给出,我们将返回主目录,行为相同,但会被记录下来)
$> pwd
/home/xieerqi
$> cd /etc
$> cd /var
$> cd /usr
$> pwd
/usr
$> cdback
Returned to:/var
$> pwd
/var
$> cd
$> pwd
/home/xieerqi
其他 shell 中的目录堆栈
csh
有自己的目录堆栈实现,但ksh
没有。您可以使用 Eddie 的实现
使用 for 循环
至于向上移动一定数量的目录,你可以编写一个函数来调用cd ..
一定次数。例如,这是我的自定义函数.bashrc
function goUp # go up x number of dirs
{
num=$1
while [ num -ne 0 ];do
cd ..
num=$( expr $num - 1 )
done
}
# ---
因此,我会调用这个命令来goUp 3
向上移动 3 个目录,它会调用cd ..
3 次
使用 inode 编号
此方法适用于文件夹名称包含难懂字符/无法识别的字符的情况。我们找到要使用的目录的 inode 编号,stat
然后使用find
和的组合cd
$> stat $HOME/bin/sh/
File: ‘/home/xieerqi/bin/sh/’
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: 801h/2049d Inode: 5795531 Links: 2
Access: (0775/drwxrwxr-x) Uid: ( 1000/ xieerqi) Gid: ( 1000/ xieerqi)
Access: 2015-08-19 15:27:38.280529273 -0600
Modify: 2016-02-20 17:03:49.822700405 -0700
Change: 2016-02-20 17:03:49.822700405 -0700
Birth: -
$> cd $(find $HOME -inum 5795531 -type d 2>/dev/null)
$> pwd
/home/xieerqi/bin/sh
当然这可能会有点慢,因为find
会递归遍历整个目录树。
答案2
如果你进入 ~/really/long/directory/name,并且只想进入 ~/really/long,那么cd ~/really/long
即使你处于 'long' 的子目录中,你也可以使用
如果你刚刚离开了 ~/really/long 并且想要回到那里,你可以这样做
Cd
然后使用向上箭头通过命令历史记录找到您使用过的位置
Cd ~/really/long