blm@cxsea.UUCP (Brian Matthews) (08/26/85)
> ** If you want it, it's yours. All I ask in return is that if you > ** figure out how to do this in a Bourne Shell script you send me > ** a copy. Here 'tis. It basically uses expr to hack apart the requested path, and do mkdir's on all the intermediate components. I wrote it a while ago, but haven't used it much, but I do think it works well. There are three known problems: 1. It's slow. 2. It doesn't trap any signals, so you can hit delete and have half of a path made. This doesn't hurt anything, you may just have to do a little cleaning up. 3. It's slow. From the looks of the C source, it fixes all of the problems, so I may switch to it and toss this. I called it md, for Make Directory, kind of like Change Directory. #!/bin/sh # # md directories - make all components in a given path # # written by Brian L. Matthews, 17-Jul-84 # # md makes a directory path. Unlike mkdir, it makes all necessary # components of the path. It uses mkdir, so it should fail and succeed in # the same ways as mkdir. # md tends to be slow, and should be recoded in C someday. Oh well... # if [ $# = 0 ] # check for no arguments. If none, then # print same stuff and use same echo "$0: arg count" # exit status as mkdir exit 2 fi while [ -n "$1" ] # Loop through all arguments by # looking at the first and shifting # when done with it. do made= # $made tracks the components made # so far need=$1 # $need tracks what's left to make if [ `expr $need : '/.*'` = 0 ] # if $need doesn't start with a slash, then # add a slash, and say we've made made=`pwd` # the current working directory. need=/$need fi while [ -n "$need" ] # keep going until we've got it all do made=$made`expr $need : '\(.[^/]*\)/*'` # add the first component of $need to # $made. If $made was /u and $need # was /blm, $made would become # /u/blm if [ ! -d "$made" -o ! -w "$made" ] then # if $made isn't a directory or it's mkdir $made # not writable (i.e. it doesn't if [ $? != 0 ] # exist), do a mkdir. If the mkdir then # fails, exit with it's exit code. exit $? # mkdir has already printed the error. fi fi need=`expr $need : '.[^/]*\(/*.*\)'` # remove the first component of $need. done # we've now made a path, so scoot the shift # arguments down, and do the next one. done exit 0 Brian L. Matthews ...uw-beaver!ssc-vax!cxsea!cxsea2!arrakis!blm
stan@tikal.UUCP (Stan Tazuma) (08/27/85)
In article <309@cxsea.UUCP> blm@cxsea.UUCP (Brian Matthews) writes: >> ** If you want it, it's yours. All I ask in return is that if you >> ** figure out how to do this in a Bourne Shell script you send me >> ** a copy. > >Here 'tis. It basically uses expr to hack apart the requested path, and >do mkdir's on all the intermediate components. I wrote it a while ago, >but haven't used it much, but I do think it works well. There are three >known problems: > > 1. It's slow. > 2. It doesn't trap any signals, so you can hit delete and have half > of a path made. This doesn't hurt anything, you may just have to > do a little cleaning up. > 3. It's slow. Just to illustrate some possibly little known features of the Bourne shell, I thought I'd followup with another version of nmkdir. Expr and test can be slow enough that the use of the shell pattern matching features (the case statement) may be preferred. Also, creative use of IFS can be a big help. Here is my version: #! /bin/sh cwd=`pwd` IFS=/ # after setting IFS, anything with '/' has to be quoted. # also, IFS will take care of repeated '/'s properly. for arg { case "$arg" { /*) cd "/" ;; } for d in $arg { if test ! -d $d then if mkdir $d then : fall through else echo "Error making directory $d in dirpath $arg" exit 1 #### break fi fi if cd $d then : ok, go on else echo "Error, can't chdir to $d in dirpath $arg" exit 1 fi } cd "$cwd" } exit
naiman@pegasus.UUCP (Ephrayim J. Naiman) (08/28/85)
<munch, munch> Here's another nmkdir which makes all the directories in a given path. It doesn't use expr so it's not so slow. ========================================================== if [ $# = 0 ] then echo "$0: arg count" exit 2 fi CWD=`pwd` for i in $* do IFS=/ BUILD=. # If the directory starts with a slash we have to move there. if [ "`echo "$i" | cut -c1`" = "/" ] then cd "/" fi for j in $i do BUILD=${BUILD}/${j} if [ ! -d "$BUILD" ] then mkdir "$BUILD" # Remember the exit code because the test operator has its own exit code. EXIT=$? if [ $EXIT != 0 ] then exit $EXIT fi fi done # cd back in case there are more arguments on the argument list that do # not begin with slash. cd "$CWD" done -- ==> Ephrayim J. Naiman @ AT&T Information Systems Laboratories (201) 576-6259 Paths: [ihnp4, allegra, mtuxo, maxvax, cbosgd, lzmi, ...]!pegasus!naiman
naiman@pegasus.UUCP (Ephrayim J. Naiman) (09/02/85)
<munch, munch> > if cd $d > then : ok, go on > else > echo "Error, can't chdir to $d in dirpath $arg" > exit 1 > fi I think in the bourne shell a bad cd will terminate the shell script no matter what its return code. Therefore, as soon as a bad cd occurs, termination before any test. -- ==> Ephrayim J. Naiman @ AT&T Information Systems Laboratories (201) 576-6259 Paths: [ihnp4, allegra, mtuxo, maxvax, cbosgd, lzmi, ...]!pegasus!naiman
rbp@investor.UUCP (Bob Peirce) (09/02/85)
In order to keep things on disk that need to be accessed from time-to- time but never need changed, we created a parallel directory tree to which to move such files. These are backed up once a week or so rather than every night. To build the files we had to make directories on the fly and used the following approach: if [ ! -d $H$D ] # directory doesn't exist then # make required directories L=`echo $H$D | tr "/" ' '` I="" for i in $L do I=$I/$i if [ ! -d $I ] then mkdir $I fi done fi $H$D is the path, ex the file name. -- Bob Peirce, Pittsburgh, PA uucp: ...!{allegra, bellcore, cadre, idis} !pitt!darth!investor!rbp 412-471-5320 NOTE: Mail must be < 30K bytes/message
gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (09/03/85)
> > if cd $d > > ... > I think in the bourne shell a bad cd will terminate the shell script > no matter what its return code. Therefore, as soon as a bad cd occurs, > termination before any test. There is a simple way around this; use a subshell as in (cd $d). By way of illustration, here the the .funcs file that I source in my .profile. (Warning: the suspend() function is for the BRL SVR2 job-control Bourne shell and will not work with the AT&T SVR2 shell.) # shell functions DIRSTACK=... # for pushd, popd ch(){ if [ $# -lt 1 ] then cd else cd $1 fi PS1=`uname`:`pwd`' $ ' } j(){ (set +u; exec jove $*); } l(){ (set +u; exec ls -bCF $*); } not(){ $* if [ $? -eq 0 ] then return 1 else return 0 fi } popd(){ set $DIRSTACK if [ $# -ge 2 ] then DIRSTACK="$*" ch $1 set $DIRSTACK # ch clobbered $* shift DIRSTACK="$*" fi } print(){ (set +u; pr $* | lpr); } pushd(){ DIRSTACK=`pwd`" $DIRSTACK" if [ $# -lt 1 ] then set $HOME fi if (cd $1) then cd $1 >&- echo $DIRSTACK PS1=`uname`:`pwd`' $ ' else popd fi } if not pdp11 then suspend(){ case "$-" in *J*) set +j kill -18 $$ set -J ;; *) kill -18 $$ # SIGSTOP ;; esac } readonly suspend fi swapd(){ DIRSTACK=`pwd`" $DIRSTACK" set $DIRSTACK if [ $# -ge 3 ] then DIRSTACK="$*" ch $2 set $DIRSTACK # ch clobbered $* DIRSTACK="$1" shift 2 DIRSTACK=$DIRSTACK" $*" echo $DIRSTACK else shift DIRSTACK="$*" echo 'swapd: No previous directory' >&2 return 1 fi } readonly ch j l popd print pushd swapd