KSH的命令中是否有等效的bash pushd / popd构建?
对于那些不知道bash中pushd和popd是什么的人,这里是手册页中的描述
pushd [-n] [dir]
pushd [-n] [+n] [-n]
Adds a directory to the top of the directory stack, or rotates
the stack, making the new top of the stack the current working
directory. With no arguments, exchanges the top two directo-
ries and returns 0, unless the directory stack is empty.
popd [-n] [+n] [-n]
Removes entries from the directory stack. With no arguments,
removes the top directory from the stack, and performs a cd to
the new top directory. Arguments, if supplied, have the fol-
lowing meanings:
谢谢
答案 0 :(得分:10)
当我发现ksh不包括这些时,我写了自己的。我把它放在~/bin/dirstack.ksh
中,我的.kshrc
文件包含它:
. ~/bin/dirstack.ksh
以下是dirstack.ksh
的内容:
# Implement a csh-like directory stack in ksh
#
# environment variable dir_stack contains all directory entries except
# the current directory
unset dir_stack
export dir_stack
# Three forms of the pushd command:
# pushd - swap the top two stack entries
# pushd +3 - swap top stack entry and entry 3 from top
# pushd newdir - cd to newdir, creating new stack entry
function pushd
{
sd=${#dir_stack[*]} # get total stack depth
if [ $1 ] ; then
if [ ${1#\+[0-9]*} ] ; then
# ======= "pushd dir" =======
# is "dir" reachable?
if [ `(cd $1) 2>/dev/null; echo $?` -ne 0 ] ; then
cd $1 # get the actual shell error message
return 1 # return complaint status
fi
# yes, we can reach the new directory; continue
(( sd = sd + 1 )) # stack gets one deeper
dir_stack[sd]=$PWD
cd $1
# check for duplicate stack entries
# current "top of stack" = ids; compare ids+dsdel to $PWD
# either "ids" or "dsdel" must increment with each loop
#
(( ids = 1 )) # loop from bottom of stack up
(( dsdel = 0 )) # no deleted entries yet
while [ ids+dsdel -le sd ] ; do
if [ "${dir_stack[ids+dsdel]}" = "$PWD" ] ; then
(( dsdel = dsdel + 1 )) # logically remove duplicate
else
if [ dsdel -gt 0 ] ; then # copy down
dir_stack[ids]="${dir_stack[ids+dsdel]}"
fi
(( ids = ids + 1 ))
fi
done
# delete any junk left at stack top (after deleting dups)
while [ ids -le sd ] ; do
unset dir_stack[ids]
(( ids = ids + 1 ))
done
unset ids
unset dsdel
else
# ======= "pushd +n" =======
(( sd = sd + 1 - ${1#\+} )) # Go 'n - 1' down from the stack top
if [ sd -lt 1 ] ; then (( sd = 1 )) ; fi
cd ${dir_stack[sd]} # Swap stack top with +n position
dir_stack[sd]=$OLDPWD
fi
else
# ======= "pushd" =======
cd ${dir_stack[sd]} # Swap stack top with +1 position
dir_stack[sd]=$OLDPWD
fi
}
function popd
{
sd=${#dir_stack[*]}
if [ $sd -gt 0 ] ; then
cd ${dir_stack[sd]}
unset dir_stack[sd]
else
cd ~
fi
}
function dirs
{
echo "0: $PWD"
sd=${#dir_stack[*]}
(( ind = 1 ))
while [ $sd -gt 0 ]
do
echo "$ind: ${dir_stack[sd]}"
(( sd = sd - 1 ))
(( ind = ind + 1 ))
done
}
答案 1 :(得分:3)
如果您只需一个级别的后退跟踪即可,您可以将'cd - '或'cd $ OLDPWD'别名为popd。
至于dir.ksh ......根据谷歌它是commercial package的一部分:
请注意
popd是一个定义的KornShell函数 在文件中
$ROOTDIR/etc/dir.ksh.
此文件通常由a处理 在处理期间登录shell 文件$ ROOTDIR / etc / profile.ksh。如果 你的系统无法识别 popd命令,检查你的profile.ksh 文件以确保调用dir.ksh 包括在内。
AVAILABILITY
适用于超级用户MKS的MKS工具包 系统管理员MKS工具包 适用于开发人员的工具包MKS Toolkit for 互操作性MKS工具包 专业开发人员MKS工具包 适用于企业开发人员MKS Toolkit 适用于企业开发人员64位 版
答案 2 :(得分:2)
我通常会使用子shell来做这类事情:
(cd tmp; echo "test" >tmpfile)
这将更改为tmp
目录,并在该目录中创建名为tmpfile
的文件。子shell返回后,当前目录将恢复到子shell启动之前的状态。这是因为每个shell实例都有自己对“当前目录”的概念,并且更改子shell中的当前目录不会影响调用它的shell。
答案 3 :(得分:1)
accepted answer中存在一个细微的错误。当不带arg($ 1 =“”)和空dir_stack的情况下调用'pushd'时,它将向该堆栈中注入一个无法“弹出”的空白条目。抓住边缘盒似乎可以解决问题。
这是更正的代码。编辑:无处推送时抱怨stderr(一致w / bash推送)。我认为这是一种改进,因此将索引列表留在“目录”上:')
# Implement a csh-like directory stack in ksh
#
# environment variable dir_stack contains all directory entries except
# the current directory
unset dir_stack
export dir_stack
# Three forms of the pushd command:
# pushd - swap the top two stack entries
# pushd +3 - swap top stack entry and entry 3 from top
# pushd newdir - cd to newdir, creating new stack entry
function pushd
{
sd=${#dir_stack[*]} # get total stack depth
if [ $1 ] ; then
if [ ${1#\+[0-9]*} ] ; then
# ======= "pushd dir" =======
# is "dir" reachable?
if [ `(cd $1) 2>/dev/null; echo $?` -ne 0 ] ; then
cd $1 # get the actual shell error message
return 1 # return complaint status
fi
# yes, we can reach the new directory; continue
(( sd = sd + 1 )) # stack gets one deeper
dir_stack[sd]=$PWD
cd $1
# check for duplicate stack entries
# current "top of stack" = ids; compare ids+dsdel to $PWD
# either "ids" or "dsdel" must increment with each loop
#
(( ids = 1 )) # loop from bottom of stack up
(( dsdel = 0 )) # no deleted entries yet
while [ ids+dsdel -le sd ] ; do
if [ "${dir_stack[ids+dsdel]}" = "$PWD" ] ; then
(( dsdel = dsdel + 1 )) # logically remove duplicate
else
if [ dsdel -gt 0 ] ; then # copy down
dir_stack[ids]="${dir_stack[ids+dsdel]}"
fi
(( ids = ids + 1 ))
fi
done
# delete any junk left at stack top (after deleting dups)
while [ ids -le sd ] ; do
unset dir_stack[ids]
(( ids = ids + 1 ))
done
unset ids
unset dsdel
else
# ======= "pushd +n" =======
(( sd = sd + 1 - ${1#\+} )) # Go 'n - 1' down from the stack top
if [ sd -lt 1 ] ; then (( sd = 1 )) ; fi
cd ${dir_stack[sd]} # Swap stack top with +n position
dir_stack[sd]=$OLDPWD
fi
else
# ======= "pushd" =======
# swap only if there's a value to swap with
if [ ${#dir_stack[*]} = "0" ]; then
echo "ksh: pushd: no other directory" >&2
else
cd ${dir_stack[sd]} # Swap stack top with +1 position
dir_stack[sd]=$OLDPWD
fi
fi
}
function popd
{
sd=${#dir_stack[*]}
if [ $sd -gt 0 ] ; then
cd ${dir_stack[sd]}
unset dir_stack[sd]
else
cd ~
fi
}
function dirs
{
echo "0: $PWD"
sd=${#dir_stack[*]}
(( ind = 1 ))
while [ $sd -gt 0 ]
do
echo "$ind: ${dir_stack[sd]}"
(( sd = sd - 1 ))
(( ind = ind + 1 ))
done
}
答案 4 :(得分:0)
如果您的系统无法识别pushd命令,请检查您的profile.ksh文件以确保包含对dir.ksh的调用。