在系统管理的多个目录之间切换的快速命令行方式是什么?我的意思是,我可以使用pushd .
和popd
进行切换,但是如果我想存储多个并循环它们,而不是永久地将它们从堆栈底部弹出怎么办?
答案1
bash
内置pushd
于+
和-
options 可以旋转目录堆栈。语法可能有点令人困惑,可能是因为该堆栈是一个零基于数组。这些简单的包装函数在目录堆栈中循环:
# cd to next directory in stack (left rotate)
ncd(){ pushd +1 > /dev/null ; }
# cd to previous directory in stack (right rotate)
pcd(){ pushd -0 > /dev/null ; }
测试:设置四个目录的堆栈。
dirs -c # clear directory stack
cd /home ; pushd /etc ; pushd /bin ; pushd /tmp
现在/tmp是当前目录,堆栈如下所示:
/tmp /bin /etc /home
更改到堆栈中的下一个目录(并显示它)四次:
ncd ; pwd ; ncd ; pwd ; ncd ; pwd ; ncd ; pwd
输出:
/bin
/etc
/home
/tmp
更改到堆栈中的上一个目录(并显示它)四次:
pcd ; pwd ; pcd ; pwd ; pcd ; pwd ; pcd ; pwd
输出:
/home
/etc
/bin
/tmp
关于cd -
:通配符回答帮助说明如何cd -
不使用$DISTACK数组,(它使用$OLDPW变量),这样cd -
就不会影响$DISTACK基于堆栈的交换应该如此。为了纠正这个问题,这里有一个简单的$DISTACK-基于交换功能:
scd() { { pushd ${DIRSTACK[1]} ; popd -n +2 ; } > /dev/null ; }
测试:
dirs -c; cd /tmp; \
pushd /bin; \
pushd /etc; \
pushd /lib; \
pushd /home; \
scd; dirs; scd; dirs
输出:
/bin /tmp
/etc /bin /tmp
/lib /etc /bin /tmp
/home /lib /etc /bin /tmp
/lib /home /etc /bin /tmp
/home /lib /etc /bin /tmp
答案2
然后使用pushd
目录堆栈中目录的特殊名称:~1
、~2
等。
例子:
tmp $ dirs -v
0 /tmp
1 /tmp/scripts
2 /tmp/photos
3 /tmp/music
4 /tmp/pictures
tmp $ cd ~3
music $ dirs -v
0 /tmp/music
1 /tmp/scripts
2 /tmp/photos
3 /tmp/music
4 /tmp/pictures
music $ cd ~2
photos $ cd ~4
pictures $ cd ~3
music $ cd ~1
scripts $
使用这种方式最有效的方法pushd
是加载你的目录列表,然后再添加一个目录成为当前目录,然后您可以在静态数字之间跳转,而不会影响堆栈中目录的位置。
还值得注意的是,它将cd -
带您到您上次所在的目录。 所以将cd ~-
。
~-
相对 just的优点-
是 是-
特定于 的cd
,而~-
是扩展的通过你的外壳~1
与、~2
等相同。当在很长的目录路径之间复制文件时,这会派上用场;例如:
cd /very/long/path/to/some/directory/
cd /another/long/path/to/where/the/source/file/is/
cp myfile ~-
上式等价于:
cp /another/long/path/to/where/the/source/file/is/myfile /very/long/path/to/some/directory/
答案3
我建议你安装法西德。它使您能够通过仅输入目录名称的一小部分来快速跳转到您已经所在的任何目录。
示例:如果您访问过,则只需输入例如/home/someName/scripts/
即可跳转到那里。z scr
这比记住历史堆栈或类似内容中的顺序要方便得多。
答案4
我编写了一个脚本xyzzy
来执行此操作:
#!/bin/bash
i="$1"
i=$((${i//[^0-9]/}))
i="$(($i-1+0))"
b="$2"
b=$((${b//[^0-9]/}))
b="$(($b-1+0))"
if [ -z "$XYZZY_INDEX" ]; then
XYZZY_INDEX="$((-1))"
fi
if [ ! -f "/tmp/xyzzy.list" ]; then
touch /tmp/xyzzy.list
chmod a+rw /tmp/xyzzy.list
fi
readarray -t MYLIST < /tmp/xyzzy.list
showHelp(){
read -r -d '' MYHELP <<'EOB'
xyzzy 1.0
A command for manipulating escape routes from grues. Otherwise known as a useful system admin
tool for storing current directories and cycling through them rapidly. You'll wonder why this
wasn't created many moons ago.
Usage: xyzzy [options]
help/-h/--help Show the help.
this/-t/--this Store the current directory in /tmp/xyzzy.list
begone/-b/--begone Clear the /tmp/xyzzy.list file. However, succeed with a number and
it clears just that item from the stored list.
show/-s/--show Show the list of stored directories from /tmp/xyzzy.list
. # Use a number to 'cd' to that directory item in the stored list. This syntax is odd:
. xyzzy 2
...would change to the second directory in the list
. [no options] Use the command alone and it cd cycles through the next item in the stored
list, repeating to the top when it gets to the bottom. The dot and space before xyzzy
is required in order for the command to run in the current shell and not a subshell:
. xyzzy
Note that you can avoid the odd dot syntax by adding this to your ~/.bashrc file:
alias xyzzy=". xyzzy"
and then you can do "xyzzy" to cycle through directories, or "xyzzy {number}" to go to a
specific one.
May you never encounter another grue.
Copyright (c) 2016, Mike McKee <https://github.com/volomike>
EOB
echo -e "$MYHELP\n"
}
storeThis(){
echo -e "With a stroke of your wand, you magically created the new escape route: $PWD"
echo "$PWD" >> /tmp/xyzzy.list
chmod a+rw /tmp/xyzzy.list
}
begoneList(){
if [[ "$b" == "-1" ]]; then
echo "POOF! Your escape routes are gone. We bless your soul from the ever-present grues!"
>/tmp/xyzzy.list
chmod a+rw /tmp/xyzzy.list
else
echo -n "Waving your wand in the dark, you successfully manage to remove one of your escape routes: "
echo "${MYLIST[${b}]}"
>/tmp/xyzzy.list
chmod a+rw /tmp/xyzzy.list
for x in "${MYLIST[@]}"; do
if [[ ! "$x" == "${MYLIST[${b}]}" ]]; then
echo "$x" >> /tmp/xyzzy.list
fi
done
fi
}
showList(){
echo -e "These are your escape routes:\n"
cat /tmp/xyzzy.list
}
cycleNext(){
MAXLINES=${#MYLIST[@]}
XYZZY_INDEX=$((XYZZY_INDEX+1))
if [[ $XYZZY_INDEX > $(($MAXLINES - 1)) ]]; then
XYZZY_INDEX=0
fi
MYLINE="${MYLIST[${XYZZY_INDEX}]}"
cd "$MYLINE";
}
switchDir(){
MYLINE="${MYLIST[${i}]}"
cd "$MYLINE";
}
if [[ "$@" == "" ]];
then
cycleNext
fi;
while [[ "$@" > 0 ]]; do case $1 in
help) showHelp;;
--help) showHelp;;
-h) showHelp;;
show) showList;;
-s) showList;;
--show) showList;;
list) showList;;
this) storeThis;;
--this) storeThis;;
-t) storeThis;;
begone) begoneList;;
--begone) begoneList;;
*) switchDir;;
esac; shift
done
export XYZZY_INDEX
我使用它的方法是复制到/usr/bin
文件夹中,然后chmod a+x
在其上。然后,我编辑我的根和用户帐户~/.bashrc
文件以在底部包含以下行:
alias xyzzy='. xyzzy'
alias xy='. xyzzy'
“xy”是命令的缩写形式,用于加快打字速度。
然后,我可以将当前目录存储在列表中......
xyzzy this
...并根据需要重复。一旦我用我需要的目录填充了这个列表,它们就会保留在那里,直到我重新启动计算机,因为那时 /tmp 会再次被清除。然后我可以输入...
xyzzy show
...列出当前保存的目录。为了切换到目录,我有两种选择。一种选择是通过索引指定路径(它是基于 1 的索引),如下所示:
xyzzy 2
...这将切换到列表中第二项的目录。或者,我可以省略索引号,然后执行以下操作:
xyzzy
...让它根据我的需要循环遍历每个目录。要了解更多可以执行的命令,请键入:
xyzzy help
当然,使用我添加的愚蠢的 echo 语句,工作会更有趣。
请注意,xyzzy 是对巨洞文本冒险,输入 xyzzy 可以让你在游戏中的两个房间之间切换,以避免出现麻烦。