adamm%bbn-unix@sri-unix.UUCP (01/05/84)
From: Adam Moskowitz <adamm@bbn-unix> Help ! I'm trying to make a command via some combination of aliases and script files that will allow the following scenario to take place : bbns /usr/adamm --> cd /usr/dir1/dir2/dir3 bbns /usr/dir1/dir2/dir3 --> cat file1 bbns /usr/dir1/dir2/dir3 --> wc file2 bbns /usr/dir1/dir2/dir3 --> plugh /usr/adamm/dirA/dirB # THIS ONE ! bbns /usr/adamm/dirA/dirB --> vi fileX bbns /usr/adamm/dirA/dirB --> foo fileX bbns /usr/adamm/dirA/dirB --> plugh # THIS ONE TOO ! bbns /usr/dir1/dir2/dir3 --> where the --> and everything to the LEFT of it is the prompt. What I need is the stuff to do the 'plugh' command. If I call it with an arg, it should 'cd' to that place and remember where it came from. If I call it with no args, it should 'cd' me back to the last place I 'plugh'd from (with an arg, of course). The problem I've had was that I couldn't find a way to get a shell script to leave me where it 'cd'd to. When I resorted to 'source'ing the script file, I couldn't figure out how to pass args to the script. Please let me know if you have such a command or know how I can do this. I'd be glad to re-distribute the results if/when I get them. Thanx, AdamM (adamm@bbn-unix)
condict@csd1.UUCP (Michael Condict) (01/07/84)
All you need is a way to execute "source" commands with argument(s) after the file name, right? Well, to prove that this is completely straightforward in the elegant and powerful mechanism loosely known as the C-shell (4.2bsd), I hereby enclose a copy of my .cshrc file, which contains the desired alias (called "so", below). Use it with: so file [args] With no args it is equivalent to "source file" (but a tad slower). Note that, at no extra charge, I provide you with a one-line while loop and a "cd" command that sources a .cdrc file upon entering a directory (the latter is an optional accessory, but "while1" is needed by "so"). I posted this before as a puzzle, with no comments -- didn't think I'd ever find that somebody actually wanted it! Michael Condict ...!cmcl2!csd1!condict P.S. Neither I nor my heirs and/or creditors are responsible for the correct functioning of any part of this "code", especially if any character of it is changed. P.P.S. This code memorializes the closest I've ever come to hacker's paradise. I can still feel the adrenaline coursing through my veins as I eradi- cated the last bug with a carefully placed "\\\'\''" ... ------------------------------------------------------------------------------ # alias l 'ls -l' alias m 'more' alias rm '/bin/rm -i' alias h history # # A one-line while loop (can be used in aliases): alias while1 'eval "if (" \!:1 ")'\ 'eval \!:2:q \; while1 '\\\''\!:1:q'\\\' \\\''\!:2:q'\\\'\" # # Executes a source command with arguments (placed in argv, which is # saved and restored) and with local variables (see local, below): set stack = ("ENDFRAME") alias so 'set stack = ("ENDFRAME" $stack:q);'\ 'local argv;'\ 'set argv=(\!*);'\ 'if ($#argv == 0) source;'\ 'if ($#argv > 0) eval'\ \''set stack = (" " $stack:q);'\ '@ stack[1] = 1;'\ 'if ("$argv[1]" =~ /*) @ stack[1] += $#path;'\ 'while1 '\'\\\'\''$stack[1] <= $#path'\'\\\'\ \\\'\''if (-x "$path[$stack[1]]"/$argv[1])'\ '@ stack[1] += $#path;'\ '@ stack[1] += 1'\'\\\'\'' ;'\ '@ stack[1] -= (1 + $#path);'\ 'if ($stack[1] > 0)'\ 'set argv[1] = "$path[$stack[1]]"/$argv[1];'\ 'shift stack;'\ 'eval "shift; source $argv[1]"'\'';'\ 'unlocal; shift stack' # # Use at top of an "so" file (see above) to declare local vars of the file # (ones whose lifetime should coincide with the execution of the "so" file) alias local 'if ("\!:2*" != "") eval local \!:2*;'\ 'if (! $?\!{:1})'\ 'set stack = ("unset \!:1" $stack:q);'\ 'if ($?\!{:1}) eval'\ \''set stack = ("shift stack;'\ 'set \!:1 = ("\$"stack[1-$#\!{:1}]:q);'\ 'set stack = ("\$"stack[$#\!{:1}-]:q)"'\ '$\!{:1}:q $stack:q);'\ 'if ($#\!{:1} == 0) set stack[1] = "set \!:1 = ()"'\' # # Use to restore vars saved with local, above. There must be an occurrence # of "ENDFRAME" as a word in $stack: alias unlocal 'eval "$stack[1]"; shift stack;'\ 'if ("$stack[1]" != "ENDFRAME") eval unlocal' # # The following will act like cd but will execute file .cdrc # (using 'so', above) if it is found in the # new directory, with args consisting of the new dir followed by any # additional args to cd: #alias cd 'set cd=(\!*);'\ # 'if ($#cd == 0) set cd = ~;'\ # 'eval chdir $cd[1]:q;'\ # 'if (-r .cdrc) eval so .cdrc '\''$cd:q'\''; unset cd' ----------------------------------------------------------------------------
terryl@teklabs.UUCP (Terry Laskodi) (01/08/84)
Well, if you're using a 4.1-based CSH (or later), then there's a really easy way to do it just with aliases!!! No C-shell scripts needed!!! alias cd 'cd \!*;set prompt="$cwd"' alias pushd 'pushd \!*;set prompt="$cwd"' alias popd 'popd;set prompt="$cwd"' Quotes must be used exactly as above, but any other strings can be put in the set prompt string.
thomas@utah-gr.UUCP (Spencer W. Thomas) (01/10/84)
1. The "plugh" command you show is pretty well covered by the pushd command in 4bsd and later c-shells. If you are still in v7-land, the following should do it: alias plugh 'if ( "\!*" == "" ) cd $prevdir;'\ 'if ( "\!*" != "" ) cd \!*;'\ 'set prevdir = $cwd' alias cd 'cd \!*; set cwd=`pwd`' 2. To get your current directory in the prompt, the following aliases will do it (assuming 4bsd csh, which automatically sets the cwd variable): alias cd 'cd \!*; setprompt' alias pd 'pushd \!*; setprompt' alias popd 'popd \!*; setprompt' set baseprompt = bbna alias setprompt 'set prompt="$baseprompt $cwd >"' A slightly fancier version takes into account your favorite csh variables to abbreviate the directory name: alias sortset source ~/bin/sortset set baseprompt = "$prompt:q" alias setprompt 'set prompt="["`echo $cwd | sed -f ~/.set`"]$baseprompt:q"' This gives a prompt like [$foo/bar] utah-gr> The sortset script is given below. It contains as special cases a few variables that I do NOT want to see in my prompt. set | awk '/^ds/ { next; }\ /^old/ { next; }\ /^cwd/ { next; }\ / \// { if (NF == 2) print length($2), $0; }\ { next; }' | sort -rn |\ awk '{ if ($3 != "'${HOME}'") printf "s;%s;$%s;\n", $3, $2; }\ END { print "s;'${HOME}';~;"; }' >~/.set =Spencer
toml@oliveb.UUCP (Dave Long) (01/10/84)
Actually, if you're going to do this, and you are using 4.1BSD this following stack-oriented command should provide a better arrangement. In the .login or equivalent: set dsp=0 set dr="" set ds=(. . . . . . . . . . . . . . . .) In the .cshrc or equivalent: alias pushd 'set dr=\!*;cd $dr;@ dsp++;set ds[$dsp]=$dr' alias popd 'set ds[$dsp]=".";@ dsp--;set dr=$ds[$dsp];cd $dr' alias printd 'echo $ds' a sample session is as follows: (the '> ' is the prompt) > pwd /usr/foo > pushd /usr/bletch > printd /usr/bletch . . . . . . . . . . . . . > pwd /usr/bletch > pushd /usr/bletch/bar > printd /usr/bletch /usr/bletch/bar . . . . . . . . . . > pwd /usr/bletch/bar > popd > pwd /usr/bletch . . . Dave Long {ucbvax,decvax}!decwrl!ios!oliveb!toml
dhb@rayssd.UUCP (01/13/84)
If you are using the newest version of csh (4.1 or later) then what you want is the builtin command "pushd". There is also a "popd" command which puts you back and a "dirs" command which prints out the contents of the directory stack. -- Dave Brierley Raytheon Co.; Portsmouth RI; (401)-847-8000 x4073 ...!decvax!brunix!rayssd!dhb ...!allegra!rayssd!dhb ...!linus!rayssd!dhb