Friday, April 27, 2012

back and forward in bash

One of the things I like about window-based file-browsing is the back and forward buttons...

So here're my bash scripts. Feel free to use them. If you find them handy buy me a beer (or post a comment)! Unless, of course, you're planning to profit off 'em, then you can and should buy me a brewery after asking my permission.

There are four files. mycd.sh, back.sh, fwd.sh, and mycdlist.sh
They have to be run in a way I just learned about today (in order to export the variables back to the running bash session) using "source" or "." (explained further, below)

I have added the following to my ~/.bash_profile:
####### For scripts, etc. that need to export variables back to bash ######
# create the script as normal
# all variables in the script are set when returning to bash...
# so best to use this only when all variables are safe...
# (Maybe call another script from the one that's exporting variables?)
# either call them as ". script.sh", "source script.sh" or add them here:
# alias script="source script.sh"
alias cd="source ~/myexecs/mycd.sh"
alias back="source ~/myexecs/back.sh"
alias fwd="source ~/myexecs/fwd.sh"
alias cdls="source ~/myexecs/mycdlist.sh"

So, I have overridden bash's "cd" command with my own... we'll see how safe this is with some testing, but currently it seems to work great. (Thinking about using this method for rm to move things to the trash... not sure yet. The trash is kinda annoying sometimes. Or at least to require a verification beforehand...)

mycd.sh is called just like a normal "cd" command, and should, in fact, work identically, with the addition of creating a variable for history...
back.sh is a simple command, has no arguments, steps one step back in the history written by mycd.sh. As set up in my bash-profile, it's called by typing "back" at the command prompt
fwd.sh does the opposite (called by typing "fwd")
mycdlist.sh lists the history and shows where you are currently (no arguments). I call it by "cdls" and its output looks like this (after calling "back" once):
MYCDPOS='1'
MYCDLASTPOS='2'
[0]='/Users/meh'
[1]='/Users/meh/Another Directory' <-- You Are Here [2]='/Users/meh/Another Directory/AndYetAnother' Here are the files (Don't forget to chmod +x). Oh, one thing... I'm not a genius, and lots of what's in here is new to me as of the past few hours... it hasn't been tested for longer than that. I'll post updates if I revise these. ******** mycd.sh: #!/bin/bash if [ "$MYCDPOS" == "" ] ; then MYCDLASTPOS=0 MYCDPOS=0 MYCDHIST[0]="$PWD" # Make these available to scripts that are called WITHOUT "source" # (Actually, I don't think this works... mycdlist was difficult with this assumption) export MYCDLASTPOS export MYCDPOS export MYCDHIST fi MYCDPOS=$(( MYCDPOS + 1 )) if [ $(( MYCDLASTPOS >= $MYCDPOS )) -eq 1 ] ; then
echo "- Overwriting history -"
fi


MYCDLASTPOS=$MYCDPOS

#echo "$@"

#cd "$@"
### Stolen from /usr/bin/cd from: $FreeBSD: src/usr.bin/alias/generic.sh,v 1.2 2005/10/24 22:32:19 cperciva Exp $
#builtin ${0##*/} ${1+"$@"}
# Doesn't work, I assume, because this is technically mycd.sh even though it's aliased as cd
builtin cd ${1+"$@"}

MYCDHIST[$MYCDPOS]="$PWD"


*************** back.sh:


#!/bin/bash

# Check if there's any history yet...
if [ "$MYCDPOS" == "" ] ; then
echo "- No history yet -"

# Check if there's still history to enter
elif [ $((MYCDPOS - 1)) -lt 0 ] ; then
echo "- End of history -"

#This shouldn't happen in the back case, but it's still a decent test...
elif [ "${MYCDHIST[$((MYCDPOS - 1))]}" != "" ] ; then

MYCDPOS=$(( MYCDPOS - 1 ))

# Check if we're entering old history...
# This happens when back is used a couple times
# then mycd is used, then fwd is used...
# mycd will place new entries beginning at the last
# position used (via back/forward),
# which might overwrite a history entry,
# but it doesn't clear all entries
# This doesn't matter, but it might be helpful to know
if [ $((MYCDPOS > MYCDLASTPOS)) -eq 1 ] ; then
echo "- In old history -"
fi

echo "'${MYCDHIST[$MYCDPOS]}'"
builtin cd "${MYCDHIST[$MYCDPOS]}"

# WTF?
else
echo "- WTF? -"
fi




***************** fwd.sh:


#!/bin/bash

# Check if there's any history yet...
if [ "$MYCDPOS" == "" ] ; then
echo "- No history yet -"

# Check if there's still history to enter
elif [ "${MYCDHIST[$((MYCDPOS + 1))]}" != "" ] ; then

MYCDPOS=$(( MYCDPOS + 1 ))

# Check if we're entering old history...
# This happens when back is used a couple times
# then mycd is used, then fwd is used...
# mycd will place new entries beginning at the last
# position used (via back/forward),
# which might overwrite a history entry,
# but it doesn't clear all entries
# This doesn't matter, but it might be helpful to know
if [ $((MYCDPOS > MYCDLASTPOS)) -eq 1 ] ; then
echo "- Entering old history -"
fi

echo "'${MYCDHIST[$MYCDPOS]}'"
builtin cd "${MYCDHIST[$MYCDPOS]}"

# Reached the end of the history
else
echo "- End of history -"
fi


***************** mycdlist.sh:


#!/bin/bash

MYCDTEMPitemNum=0

echo "MYCDPOS='$MYCDPOS'"
echo "MYCDLASTPOS='$MYCDLASTPOS'"
#Allegedly (and experimentally) there's no way to export arrays
#Thus mycdlist.sh must also be called via "source" or "."
#even though it's only *reading* the variables which are shown
#in bash when you type "set." I'm no export expert, this is kinda voodoo to me.

#echo "MYCDHIST="

if [ "$MYCDPOS" != "" ] ; then
while [ 1 ]
do
MYCDTEMPitem="${MYCDHIST[$MYCDTEMPitemNum]}"
# echo "item='$MYCDTEMPitem'"
if [ "$MYCDTEMPitem" == "" ] ; then
break
else
if [ $MYCDTEMPitemNum -eq $MYCDPOS ] ; then
echo "[$MYCDTEMPitemNum]='$MYCDTEMPitem' <-- You Are Here"
else
echo "[$MYCDTEMPitemNum]='$MYCDTEMPitem'"
fi
fi
MYCDTEMPitemNum=$(( MYCDTEMPitemNum + 1 ))
done
else
echo "- No history -"
fi


************ That's it! I suppose zip files would be nicer...

No comments:

Post a Comment