I am writing a ksh function (that is placed in the .profile file) that will present a menu of subdirectories and permit the user to choose one into which to cd. Here is the code:
# Menu driven subdirectory descent.
d(){
# Only one command line argument accepted
[ "$1" = "--" ] && shift $# # Trap for "ls --" feature
wd=`pwd`; arg="${1:-$wd}"
dirs="`/bin/ls -AF $arg 2>/dev/null | grep /$ | tr -d \"/\"`"
# Set the names of the subdirectories to positional parameters
if [ "$dirs" ] ;then
set $dirs
if [ $# -eq 1 -a "$arg" = "$wd" ] ;then cd $arg/$1; return; fi # trap: it's obvious; do it
else echo "No subdirectories found" >&2; return 1
fi
# Format and display the menu
if [ `basename "${arg}X"` = "${arg}X" ] ;then arg="$wd/$arg"; fi # Force absolute path if relitive
echo -e "\n\t\tSubdirectories relative to ${arg}: \n"
j=1; for i; do echo -e "$j\t$i"; j=`expr $j + 1`; done | pr -r -t -4 -e3
echo -e "\n\t\tEnter the number of your choice -- \c "
# Convert user-input to directory-name and cd to it
read choice; echo
dir=`eval "(echo $\{"$choice"\})"` # Magic here.
[ "$choice" -a "$choice" -ge 1 -a "$choice" -le "$#" ] && cd $arg/`eval echo "$dir"`
}
This function works reasonably well with the exception of directory names that contain space characters. If the directory name contains a space, the set command sets each space delimited element of the directory name (instead of the complete directory name) into a separate positional parameter; that is not useful here.
I have attempted to set the $IFS shell variable (which contains a space, tab, and newline by default) to a single newline character with:
IFS=`echo` # echo outputs a trailing newline character by default
Which appears to accomplish what is intended as verified with:
echo -e "$IFS\c" | hexdump -c
But despite my best efforts (over the course of several days work) I have failed to set the entire directory names that contain spaces as values for positional parameters.
What am I missing?
Suggestions are hereby solicited and most welcome.
ADVAthanksNCE
Bob