jlh@loral.UUCP (Physically Pffft) (11/22/88)
Our application has it's source code in 9 directories, and I find that often I need to make similar changes in all 9 directories. Manually cd'ing into each directory is error prone, some are skipped and others are entered more than once. I'd like to write a shell script to automate this that would act as follows: 1. Enter all the directory names into a file (only need to do once) 2. Invoke the script, it reads the first directory from the file and cd's into it. It then suspends itself. 3. I do what I need to. 4. I enter 'next' or something to wake up the script, it reads the next directory from the file and cd's into it. Steps 2-4 are done for all directories. My problem is I don't know how to suspend a shell script like this, and then have it continue where it left off. My only idea is to create a new shell ('/bin/sh'), but I think this would be slower than snail snot. Anyone have any ideas? Thanks. Jim -- Jim Harkins jlh@loral.cts.com Loral Instrumentation, San Diego
logan@vsedev.VSE.COM (James Logan III) (11/23/88)
In article <1872@loral.UUCP> jlh@loral.UUCP (Physically Pffft) writes: >Our application has it's source code in 9 directories, and I find that >often I need to make similar changes in all 9 directories. Manually >cd'ing into each directory is error prone, some are skipped and others >are entered more than once. I'd like to write a shell script to automate >this that would act as follows: > >1. Enter all the directory names into a file (only need to do once) >2. Invoke the script, it reads the first directory from the file and > cd's into it. It then suspends itself. >3. I do what I need to. >4. I enter 'next' or something to wake up the script, it reads the next > directory from the file and cd's into it. Steps 2-4 are done for > all directories. > >My problem is I don't know how to suspend a shell script like this, and then >have it continue where it left off. My only idea is to create a new shell >('/bin/sh'), but I think this would be slower than snail snot. Anyone >have any ideas? Thanks. Invoking another instance of /bin/sh should not be slow since the text segment of /bin/sh is shared by more than one process. I wrote you the following shell script that runs VERY quickly on my system. It will handle the requirements you posted. Just type "^D" (control-D) or "exit" to go to the next directory. -Jim ------------ CUT HERE -------------- # autocd.sh James Logan Tue Nov 22 18:27:16 EST 1988 # Read a list of directories from $DIRFILE and invoke # an interactive shell for each directory. # # Set DIRFILE if not already set to something else in the # user's environment. # DIRFILE=${DIRFILE:-"dirs"}; if test ! -r "$DIRFILE"; then echo >&2 "$0: Cannot read '$DIRFILE'."; exit 1; fi; # # Feed the file $DIRFILE into stdin and read a line at a time. # while read DIR; do echo "\nChanging to directory '$DIR'"; if cd $DIR; then PS1="$DIR> "; export PS1; # Redirect stdin from user's tty -- it is currently # connected to $DIRFILE (inherited from the while loop). sh -i </dev/tty; fi; done <$DIRFILE; echo "\07\nDone.\07"; -------------- CUT HERE ------------------ -- Jim Logan logan@vsedev.vse.com (703) 892-0002 uucp: ..!uunet!vsedev!logan inet: logan%vsedev.vse.com@uunet.uu.net
daniel@island.uu.net (Dan "1461 days of Bush is 1462 too many..." Smith) (11/24/88)
In article <1872@loral.UUCP> jlh@loral.UUCP (Physically Pffft) writes: >Our application has it's source code in 9 directories, and I find that >often I need to make similar changes in all 9 directories. Manually >cd'ing into each directory is error prone, some are skipped and others >are entered more than once. I'd like to write a shell script to automate I deal with this every single day! :-) Here's my strategy/tutorial: use foreach to pushd all of the directories in a tree [optionally set up a label] do whatever needs to be done the directory pop the directory [optionally goto the label] so from csh you could have: (skip RCS directories) % foreach i (`find -name RCS -prune -o -type d -print`) ? pushd $i ? end to push all all of the directories in a tree...be careful with $cdpath, or you may not get what you want... How I usually do it... I have an alias called "fed" (foreach directory) that sources a script via: alias fed 'source ~$misc_bin_person/bin/ptree' and here is "ptree" (pushd tree) ---- # note, this must be sourced... set savecdpath=($cdpath) set cdpath=( . .. ../.. ../../.. ../../../../..) echo -n looking at directories... foreach i (`find -name RCS -prune -o -type d -print`) p $i end set cdpath=($savecdpath) unset savecdpath ---- ...and here are my relevant cd/pushd/popd aliases: ----- # # aliases for setting the prompt and getting around # # fillstr is a var used in prompt, contains "(level)" when dirs are pushed set fillstr="" set end=":-)" alias prompt_set 'set prompt_head=$cwd:h;set prompt="\! $HOST"":$prompt_head:t/$cwd:t$fillstr $end "' alias cd 'set old=$cwd; chdir \!*; prompt_set; if -e .locrc source .locrc' alias dir_number 'set fillstr; set dnum=`dirs`; shift dnum; if ($#dnum >= 1) set fillstr=" ($#dnum)"' alias p 'set o2=$cwd; pushd \!* > /dev/null; set pdirs=`dirs`; echo $pdirs:gt; set old=$o2; dir_number; prompt_set' alias pp 'set o2=$cwd; popd; set old=$o2; dir_number; prompt_set' alias fed 'source ~$misc_bin_person/bin/ptree' ----- Now...getting back to handling a tree, I go up to the root directory of a product and type "fed". All of the directories get pushed, and the prompt indicates how many levels down I am. If I'm going to do something fairly repetitive, I may set up a label via: % foo: and then do whatever I need... then to pop directories I enter "pp", and my prompt changes to reflect where I am and how many directories deep... If I had set a label, I could say something like "goto foo" (note, no colon), and things will pretty much run themselves until all of the directories are popped. I take advantage of the fact that it is an error to not have a directory to pop to; that ends the loop. Hope this helps you and others that work with projects that have many directories/levels. dan -- DanSmith IslandGraphics 4000CivicCenterDr SanRafael MarinCo CA 94903 4154911000 415 332 FAST(h) 491 0402(Fax)|d: Nobodys' fault but mine| UnixFeastsMusicFilm daniel@island.uu.net unicom!daniel@pacbell.com {lll-crg,apple}!well!dansmith
dlp@gistdev.UUCP (11/24/88)
Step 3, "I do what I need to do" is going to be a lot slower than a simple execution of the shell, unless you're using Korn shell with an enormous ENV file. ~/bin/dostuff: BASEDIR=${1:-`pwd`} for NEWDIR in `find ${BASEDIR} -type d -print` do cd ${NEWDIR} echo In \"${NEWDIR}\"\; Control-D to continue. ${SHELL:=/bin/sh} done
nick@ccicpg.UUCP (Nick Crossley) (11/24/88)
In article <1872@loral.UUCP> jlh@loral.UUCP (Physically Pffft) writes: >... about how to do things to a set of directories ... > >My problem is I don't know how to suspend a shell script like this, and then >have it continue where it left off. My only idea is to create a new shell >('/bin/sh'), but I think this would be slower than snail snot. Anyone >have any ideas? Thanks. > >-- >Jim Harkins jlh@loral.cts.com >Loral Instrumentation, San Diego I do this kind of thing sufficiently often that I wrote a script to do it, and I did use a nested shell. It is fast enough for my needs; your mileage may vary. Note that handling signals is tricky - I don't guarantee correctness! The script is quite small, so I include it below. It works with sh and ksh; I don't know about csh, but I see no reason why it should not work there also. -------------- cut here --------------------------------------------------- : SCAN - take actions throughout a directory tree # Usage: scan [-c "command"] dir ... if [ X$1 = X-c ] then Command="$2" shift; shift else Command='echo "Now in `pwd` - type EOF to continue" ; exec ${SHELL-ksh}' fi exec 7<&0 { trap '' 2 ; exec find ${*-.} -type d -print ; } | { trap 'continue' 2 while read i do ( trap 2 ; cd $i ; eval $Command ) 0<&7 done } echo "Scan finished" -------------- cut here --------------------------------------------------- -- <<< standard disclaimers >>> Nick Crossley, CCI, 9801 Muirlands, Irvine, CA 92718-2521, USA Tel. (714) 458-7282, uucp: ...!uunet!ccicpg!nick
les@chinet.chi.il.us (Leslie Mikesell) (11/29/88)
In article <1872@loral.UUCP> jlh@loral.UUCP (Physically Pffft) writes: >Our application has it's source code in 9 directories, and I find that >often I need to make similar changes in all 9 directories. >My problem is I don't know how to suspend a shell script like this, and then >have it continue where it left off. My only idea is to create a new shell >('/bin/sh'), but I think this would be slower than snail snot. Anyone >have any ideas? Thanks. A) Starting a new shell in each directory should not a problem, but B) if the work just involves editing files and the directories are arranged such that a wild-card filename can be constructed for the affected files, that might be a nicer approach. For example, if you are in the parent of the 9 directories you could: vi */xfile.c */yfile.c to edit all copies of xfile.c and yfile.c. A nice thing about this method is that you can yank and put text between files and the search and "." (repeat last change) commands can be used through all the files. Les Mikesell