Domanda
C'è un equivalente del costruire bash pushd / popd in comandi per il KSH?
Per coloro che non sanno cosa pushd e popd in bash fare, qui è la descrizione della pagina 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:
Grazie
Soluzione
Quando ho scoperto che ksh non ha incluso questi, ho scritto il mio. Ho messo questo in ~/bin/dirstack.ksh
e mio file .kshrc
include in questo modo:
. ~/bin/dirstack.ksh
Ecco il contenuto della 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
}
Altri suggerimenti
Se sei OK con un solo livello di schiena di inseguimento può alias 'cd -'. O 'cd $ OLDPWD' a popd
Per quanto riguarda dir.ksh ... secondo Google è parte di un pacchetto commerciale :
NOTE
popd è una funzione definita KornShell nel file
$ROOTDIR/etc/dir.ksh.
Questo file è normalmente elaborato da un login shell durante la lavorazione di il file $ ROOTDIR / etc / profile.ksh. Se il sistema non riesce a riconoscere la il comando popd, controllare il profile.ksh file per assicurarsi che una chiamata a dir.ksh è incluso.
disponibilità
MKS Toolkit per Power Users MKS Toolkit per amministratori di sistema MKS Toolkit per sviluppatori MKS Toolkit per Interoperabilità MKS Toolkit per Professionale sviluppatori MKS Toolkit per le Imprese sviluppatori MKS Toolkit Imprese sviluppatori 64-bit Edizione
Io di solito uso una subshell per questo genere di cose:
(cd tmp; echo "test" >tmpfile)
Questo cambia la directory tmp
e crea un file chiamato tmpfile
in quella directory. Dopo il ritorno subshell, la directory corrente viene ripristinata a quello che era prima della subshell iniziato. Questo perché ogni istanza shell ha la propria idea di ciò che la "directory corrente" è, e cambiare la directory corrente in una subshell non influenza il guscio che lo ha chiamato.
C'è una sottile bug nel risposta accettata . Quando 'pushd' viene richiamato senza arg ($ 1 = "") e un dir_stack vuota, si inietta una voce vuota in detta pila che non possono essere "spuntato" fuori. Facendo il caso limite sembra risolvere il problema.
Ecco il codice corretto. EDIT: si lamentano per stderr quando nulla per spingere (coerente w / bash pushd). A sinistra l'elenco referenziato su 'dirs' come io sento che è un miglioramento: ')
# 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 il sistema non riesce a riconoscere il comando pushd, controllare il file profile.ksh per garantire che una chiamata a dir.ksh è incluso.