jerry@slhisc.uucp (Jerry Liebelson) (10/24/90)
*SEND REPLIES TO: uunet!slcpi!slhisc!jerry
Organization: Shearson Lehman Brothers, Inc.
------------------------------------------------------------------------------
SITUATION:
1. cd /tmp
2. mkdir -p a/b
3. ln -s a/b c
PROBLEM:
1. cd /tmp/c
2. pwd (output is "/tmp/c")
3. cd ..
4. pwd (output is "/tmp/a", not "/tmp" ! )
QUESTION:
Is there a way to set things in the csh such that when I do the cd ..
from /tmp/c, I will end up in /tmp and not in /tmp/a?
I tried setting the hardpaths variable but that just changes the output
of pwd when I am in /tmp/c (displaying "/tmp/a/b" instead of "/tmp/c").
COMMENT:
I know the behavior I want can be achieved in the Korn Shell. But I
am stuck with the Csh for now.
--
Jerry Liebelson uunet!slcpi!slhisc!jerry
Distributed Infrastructure (212) 341-3166 FAX: (212) 528-0101
Shearson Lehman Brothers, Inc.
--
Jerry Liebelson uunet!slcpi!slhisc!jerry
Distributed Infrastructure (212) 341-3166 FAX: (212) 528-0101
Shearson Lehman Brothers, Inc. maart@cs.vu.nl (Maarten Litmaath) (10/25/90)
In article <JERRY.90Oct24110101@sky.slhisc.uucp>, jerry@slhisc.uucp (Jerry Liebelson) writes: )... ) SITUATION: ) ) 1. cd /tmp ) 2. mkdir -p a/b ) 3. ln -s a/b c ) ) PROBLEM: ) ) 1. cd /tmp/c ) 2. pwd (output is "/tmp/c") ) 3. cd .. ) 4. pwd (output is "/tmp/a", not "/tmp" ! ) ) ) QUESTION: ) Is there a way to set things in the csh such that when I do the cd .. ) from /tmp/c, I will end up in /tmp and not in /tmp/a? Yes: alias cd 'cd `xcd $cwd \!*`' ...where `xcd' is the following shell script, located somewhere in your PATH. (You may have to change the `cd' in the alias to `chdir'.) --------------------cut here-------------------- #!/bin/sh # # alias cd 'cd `xcd $cwd \!*`' case $# in 1) echo $HOME exit 0 ;; 2) case $2 in /*) echo "$2" exit 0 ;; *..*) ;; *) echo "$1/$2" exit 0 esac esac # /a/b/c/symlink1/symlink2/../../src -> /a/b/c/src SED=' : loop s|/[^/]*/\.\.||g t loop ' echo "$1/$2" | sed "$SED" --------------------cut here-------------------- -- Waiting for this to work: cat /internet/cs.vu.nl/finger/maart
kivinen@cs.hut.fi (Tero Kivinen) (10/25/90)
In article <JERRY.90Oct24110101@sky.slhisc.uucp> jerry@slhisc.uucp (Jerry Liebelson) writes: > Is there a way to set things in the csh such that when I do the cd .. > from /tmp/c, I will end up in /tmp and not in /tmp/a? Try alias .. 'cd /$cwd:h' in your .cshrc, and then typing .. works. This will work in csh or in tcsh. -- ______ ______ _ , !Tero_Kivinen@hut.FI ! Work : +358-0-451 4032 ! / / ' ) / !Tero Kivinen ! Voice: +358-0-523 542 ! --/ --/ /-< ! ! Data : +358-0-524 207 ! (_/ (_/ / ) +---------------------+------------------------+
maart@cs.vu.nl (Maarten Litmaath) (10/26/90)
In article <KIVINEN.90Oct25125016@deathstar.hut.fi>, kivinen@cs.hut.fi (Tero Kivinen) writes: )In article <JERRY.90Oct24110101@sky.slhisc.uucp> ) jerry@slhisc.uucp (Jerry Liebelson) writes: )> Is there a way to set things in the csh such that when I do the cd .. )> from /tmp/c, I will end up in /tmp and not in /tmp/a? ) )Try alias .. 'cd /$cwd:h' in your .cshrc, and then typing .. works. )This will work in csh or in tcsh. But that doesn't deal nicely with `cd ../../foo/bar'... Following is a solution that does _and_ is completely builtin! Piece of cake right? :-) --------------------cut here-------------------- alias cd 'set tmp=(\!*); eval cd$#tmp $cwd \!*/. ../ ~; echo $cwd' alias cd0 'chdir \!$' alias cd1 'if (x\!:2 !~ x../*) set status=1'\ '&& eval cd2 /\!^:h \!:2-:s-../--'\ '|| chdir \!:2' alias cd2 'if (x\!:2 !~ x../*) set status=1'\ '&& eval cd2 /\!^:h \!:2*:s-../--'\ '|| chdir \!^/\!:2' --------------------cut here-------------------- -- Waiting for this to work: cat /internet/cs.vu.nl/finger/maart
maart@cs.vu.nl (Maarten Litmaath) (10/27/90)
Here's a slight improvement; check the output of `cd /'; furthermore you won't get into trouble if you accidentally type `cd foo/ bar' or if there is a subdirectory `0' and you type `cd0'. --------------------cut here-------------------- alias cd 'set tmp=(\!*); eval _cd_$#tmp $cwd \!*//. ../ ~; echo $cwd' alias _cd_0 'chdir \!$' alias _cd_1 'if (x\!:2 !~ x../*) set status=1'\ '&& eval _cd_x /\!^:h \!:2-:s-../--'\ '|| chdir \!:2:h' alias _cd_x 'if (x\!:2 !~ x../*) set status=1'\ '&& eval _cd_x /\!^:h \!:2*:s-../--'\ '|| chdir \!^/\!:2:h' alias pwd 'echo $cwd' --------------------cut here-------------------- -- Waiting for this to work: cat /internet/cs.vu.nl/finger/maart
rbp@investor.pgh.pa.us (Bob Peirce #305) (11/01/90)
In article <8060@star.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes: >--------------------cut here-------------------- >alias cd 'set tmp=(\!*); eval _cd_$#tmp $cwd \!*//. ../ ~; echo $cwd' >alias _cd_0 'chdir \!$' >alias _cd_1 'if (x\!:2 !~ x../*) set status=1'\ > '&& eval _cd_x /\!^:h \!:2-:s-../--'\ > '|| chdir \!:2:h' >alias _cd_x 'if (x\!:2 !~ x../*) set status=1'\ > '&& eval _cd_x /\!^:h \!:2*:s-../--'\ > '|| chdir \!^/\!:2:h' >alias pwd 'echo $cwd' >--------------------cut here-------------------- What do you do if your csh doesn't have eval and doesn't set cwd? -- Bob Peirce, Pittsburgh, PA 412-471-5320 ...!uunet!pitt!investor!rbp rbp@investor.pgh.pa.us
rbp@investor.pgh.pa.us (Bob Peirce #305) (11/01/90)
My brain damaged csh lacks eval and it doesn't set cwd. It also runs on
an Altos with worknet -- top level directories may be / or @node.
However, we do have symbolic links, so here is my solution. I have been
hacking on this for about the last day or two. It now handles 99% of
anything we might want to do here. I would dearly love to know how I
can improve it.
# Handle typical .. moves from a symbolically linked directory
# You can go home, rel, abs, .. or ../something. That's it.
# On an Altos with worknet, / may also be @node
# Some aliases may add extraneous /s so we have to squeeze them
# Logic is to check if you are going home. If not, check the first
# char of the arg to see if it is dot, /, or @.
# If we lead off with a dot and the arg is the same as the tail of
# the arg we are just doing .. Otherwise we are doing ../something.
# If we .. all the way to /, we have to set /.
# If we lead off with / or @ it is absolute.
# If we do not lead off with dot, / or @ it is relative so
# we append the arg to $cwd/.
set cwd = `pwd`
alias cd '\\
set nwd;\\
set tmp;\\
set tgt = \!*;\\
if (x\!* == "x") set nwd = $home;\\
if (x$nwd != x$home) set tmp = `echo \!* | cut -c1`;\\
if ("x\$tmp" == 'x\\\\.' && $tgt == $tgt:t) set nwd = $cwd:h;\\
if ("x\$tmp" == 'x\\\\.' && $tgt != $tgt:t) set nwd = $cwd:h/$tgt:t;\\
if ("x\$tmp" == 'x\\\\.' && $nwd == "") set nwd = /;\\
if (x$nwd != x$home && x$tmp == 'x/' || x$tmp == 'x@') set nwd = \!*;\\
if (x$nwd == "x" && \!* != '..') set nwd = $cwd/\!*;\\
chdir $nwd;\\
set cwd = `echo $nwd | tr -s '/'`'
--
Bob Peirce, Pittsburgh, PA 412-471-5320
...!uunet!pitt!investor!rbp rbp@investor.pgh.pa.ustchrist@convex.COM (Tom Christiansen) (11/02/90)
In article <1990Oct31.164203.20518@investor.pgh.pa.us> rbp@investor.pgh.pa.us (Bob Peirce #305) writes: >What do you do if your csh doesn't have eval and doesn't set cwd? Get a real system. :-) --tom
rbp@investor.pgh.pa.us (Bob Peirce #305) (11/03/90)
Yesterday I posted a note on the problem facing this user of csh who
has sym links but lacks eval and a setting mechanism for cwd. After
thinking about it more today I decided the best solution was to build
the path with a small C program and to use a short alias to drive it.
The results follow. The C program could be made smaller and, possibly
faster by not using stdio, but this works. Setting the sticky bit
also might help.
============================== csh alias ==============================
# Handle typical .. moves from a symbolically linked directory
set cwd = `/bin/pwd`
alias pwd 'echo $cwd'
alias rpwd /bin/pwd
alias rcd chdir
alias cd '\\
if (\!* == "") set tmp = $home;\\
if (\!* != "") set tmp = `glob \!*`;\\
set cwd = `/usr/local/lib/chd $cwd $tmp`;\\
chdir $cwd'
============================== C program ==============================
/* @(#) chd.c
C program for cd
*/
#include <stdio.h>
main(argc,argv)
char **argv;
int argc;
{
int i, j;
char path[256];
if (argc != 3) exit(); /* silent failure */
/* Top dir in Altos Worknet may be @node */
if (argv[2][0] == '/' || argv[2][0] == '@')
printf ("%s\n", argv[2]);
else {
strcpy(path, argv[1]);
strcat(path, "/");
strcat(path, argv[2]);
i = j = 0;
while (path[i] != '\0') {
if ( j != i) path[j] = path[i];
if (path[i] == '.' && path[i+1] == '.') {
++i;
if (j >= 2) {
j -= 2;
while (path[j--] != '/')
;
}
else j = -1;
}
++i;
++j;
}
if (j == 0)
strcpy (path, "/");
else
path[j] = '\0';
printf ("%s\n", path);
}
}
============================== END ==============================
--
Bob Peirce, Pittsburgh, PA 412-471-5320
...!uunet!pitt!investor!rbp rbp@investor.pgh.pa.us