Pregunta
¿Hay un equivalente de la acumulación fiesta pushd / popd en los comandos para el KSH?
Para los que no saben lo que pushd y popd en bash hacer, aquí es la descripción de la 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:
Gracias
Solución
Cuando descubrí que ksh no incluyó estos, escribí mi propia. Pongo esto en mi archivo y ~/bin/dirstack.ksh
.kshrc
incluye lo siguiente:
. ~/bin/dirstack.ksh
Estos son los contenidos 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
}
Otros consejos
Si estás bien con un solo nivel de seguimiento posterior que puede alias 'cd -'. O 'cd $ OLDPWD' a popd
En cuanto a dir.ksh ... según Google es parte de un paquete comercial:
NOTA
popd se define una función KornShell en el archivo
$ROOTDIR/etc/dir.ksh.
Este archivo se procesa normalmente por una iniciar sesión cáscara durante el procesamiento de el archivo $ ROOTDIR / etc / profile.ksh. Si su sistema no reconoce la popd de comandos, compruebe su profile.ksh archivo para asegurarse de que una llamada a dir.ksh está incluido.
DISPONIBILIDAD
MKS Toolkit para usuarios avanzados MKS Toolkit para administradores de sistemas MKS Kit de herramientas para desarrolladores MKS Toolkit para Toolkit Interoperabilidad MKS para Kit de herramientas de Desarrolladores Profesionales MKS Los desarrolladores de Empresa MKS Toolkit Los desarrolladores de Empresa 64-Bit Edición
Yo suelo usar un subnivel para este tipo de cosas:
(cd tmp; echo "test" >tmpfile)
Esto cambia al directorio tmp
y crea un archivo llamado tmpfile
en ese directorio. Después de las declaraciones de subshell, el directorio actual se restablece a lo que era antes de que comenzara el subnivel. Esto es porque cada instancia de shell tiene su propia idea de lo que es el "directorio actual", y cambiar el directorio actual en un subnivel no afecta a la cáscara que lo llamó.
Hay un error sutil en la respuesta aceptado. Cuando 'pushd' se invoca sin arg ($ 1 = "") y un dir_stack vacía, se inyecta una entrada en blanco en dicha pila que no se puede "estallar" fuera de. Para controlar el caso extremo parece solucionarlo.
Aquí está el código corregido. EDIT: quejarse a stderr cuando ninguna parte de empuje (consistente w / pushd bash). Salido de la lista indexada en directorios '' ya que creo que es una mejora: ')
# 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
}
Si el sistema no reconoce el comando pushd, compruebe su archivo profile.ksh para asegurar que se incluye una llamada a dir.ksh.