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.us
tchrist@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