Pergunta
Existe um equivalente da compilação festa pushd / popd em comandos para o KSH?
Para aqueles que não sabem o que pushd e popd em bash fazer, aqui é a descrição da página man
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:
Graças
Solução
Quando descobri que ksh não incluiu estes, eu escrevi o meu próprio. Eu coloquei isso em ~/bin/dirstack.ksh
e meu arquivo .kshrc
inclui-lo como este:
. ~/bin/dirstack.ksh
Eis o conteúdo de 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
}
Outras dicas
Se você estiver OK com apenas um único nível de volta rastreamento você pode 'cd -' alias. Ou 'cd $ OLDPWD' para popd
Como para dir.ksh ... De acordo com parte da Google-lo de um comercial pacote :
NOTA
popd é uma função KornShell definido no arquivo
$ROOTDIR/etc/dir.ksh.
Este arquivo é normalmente processado por um shell de login durante o processamento de o arquivo $ ROOTDIR / etc / profile.ksh. E se o sistema não reconhece a comando popd, verificar o seu profile.ksh arquivo para garantir que uma chamada para dir.ksh está incluído.
DISPONIBILIDADE
MKS Toolkit para MKS Utilizadores Avançados Toolkit para administradores de sistema MKS Toolkit para desenvolvedores MKS Toolkit para Interoperabilidade MKS Toolkit para Professional Developers MKS Toolkit for Enterprise Developers MKS Toolkit for Enterprise Os programadores 64-Bit Edição
Eu costumo usar um subshell para este tipo de coisa:
(cd tmp; echo "test" >tmpfile)
Isso muda para o diretório tmp
e cria um arquivo chamado tmpfile
nesse diretório. Após os subnível retornos, o diretório atual é restaurado para o que era antes do subshell começou. Isso ocorre porque cada instância shell tem a sua própria idéia do que o "diretório atual" é, e mudar o diretório atual em um subshell não afeta o shell que o chamou.
Há um bug sutil na resposta aceito. Quando 'pushd' é invocado sem arg ($ 1 = "") e um dir_stack vazio, ele injeta uma entrada em branco na referida pilha que não pode ser "bateu" de fora. Pegando o caso extremo parece corrigi-lo.
Aqui está o código corrigido. EDIT: reclamar a stderr quando longe de impulso (consistente w / festa pushd). Deixou a indexado listagem no 'dirs' como eu sinto que é uma melhoria: ')
# 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
}
Se o seu sistema não reconhecer o comando pushd, verificar seu arquivo profile.ksh para garantir que uma chamada para dir.ksh está incluído.