next | next | up | down | Inhalt | Uebungen | Complete | Kommentar

all, section 7.8.

7.8.  bundle

 1      #!/bin/sh
 2      PATH=/usr/ucb:/bin:/usr/bin
 3      
 4      for i
 5      do      echo "echo $i >&2"
 6              echo "cat >$i << 'Ende von $i'"
 7              cat $i
 8              echo "Ende von $i"
 9      done

Kernighan und Pike schreiben bundle Alan Hewett und James Gosling zu. Ehrgeizige Implementierungen erreichen fast die Fähigkeiten von tar.

Hier ist eine mittelprächtige Lösung ohne Funktionen, die Kataloge rekursiv bearbeitet, Zugriffsschutz berücksichtigt und mit wc eine Art Prüfsumme übermittelt:

 1      #!/bin/sh
 2      PATH=/usr/ucb:/bin:/usr/bin
 3      bundle=`pwd`/bundle             # for recursive call
 4      exit=1
 5      
 6      if [ -x /tmp ] 2> /dev/null     # not every test has -x
 7      then    has_x=yes
 8      else    has_x=
 9      fi
10      
11      case $1
12      in -r)  rflag=y; shift
13      ;; *)   rflag=n
14              echo '# to unbundle set umask and sh this file'
15              tmp=/tmp/bundle$$
16              echo 'exit=1 tmp=/tmp/bundle$$'
17              trap "trap 0; rm -f $tmp;
18                      exit \$exit" 0 1 2 3 15
19              echo 'trap "trap 0; rm -f $tmp;
20                      exit \$exit" 0 1 2 3 15'
21              echo 'exec > $tmp'; exec 3> $tmp
22      esac
23      
24      for i 
25      do      if [ -d $i ]
26              then    echo "[ -d $i ] || mkdir $i"
27                      $bundle -r $i/*
28              elif [ -r $i ]
29              then    echo "sed 's/^  //' > $i << 'End of $i'"
30                      sed 's/^/       /' $i
31                      echo "End of $i"
32                      echo "wc $i"; wc $i >&3
33                      if [ "$has_x" ]
34                      then    [ -x $i ]
35                      else    [ `expr "\`ls -l $i\`" : '...x'` = 4 ]
36                      fi && echo "chmod +x $i"
37              else    continue
38              fi
39              [ -w $i ] || echo "chmod -w $i"
40              echo "echo >&2 $i"; echo >&2 $i
41      done
42      
43      case $rflag
44      in n)   echo "diff -b - \$tmp << 'End of wc' >&2"
45              exec 3>&-
46              cat $tmp
47              echo 'End of wc'
48              exit=0
49              echo 'exit=$?'
50      esac

Die Lösung ist nicht sehr elegant, da sie sich selbst rekursiv aufruft. I bundle muß entweder auf PATH zu finden sein, oder man muß den Pfad bei der Installation explizit setzen. Außerdem wird relativ viel Code quasi verdoppelt. Dies kann man mit Funktionen vermeiden.

 1      #!/bin/sh
 2      
 3      usage() {
 4              echo >&2 "usage: `basename $0` [-y] \c"
 5              echo >&2 " file... dir... > bundle"
 6              exit 1
 7      }
 8      
 9      if [ -x /tmp ] 2> /dev/null     # not every test has -x
10      then    has_x=yes
11      else    has_x=
12      fi
13      
14      case "$1"
15      in '')  usage
16      ;; -y)  yflag=-y; shift
17              [ $# = 0 ] && usage
18      ;; *)   yflag=
19      esac
20      
21      for i
22      do      case "$i"
23              in *'
24      '* | *' '* | *' '* )    echo >&2 "$i: illegal filename"
25                              exit 1
26              esac
27      done
28      argv="$*"       
29              
30      dup() { # arg ...
31              echo "$*"
32              eval "$@"
33      }
34      
35      echo '# to unbundle set umask and sh this file'
36      echo '# specify a parameter to suppress queries'
37      
38      dup PATH=/usr/ucb:/bin:/usr/bin
39      dup exit=1
40      dup tmp='/tmp/bundle$$'
41      echo 'yflag=$1'
42      
43      dup 'trap "trap 0; rm -f $tmp; exit \$exit" 0 1 2 3 15'
44      
45      dup 'ask() {
46              if [ "$yflag" ]
47              then    echo >&2 $*
48              else    if [ "`echo -n`" ]
49                      then    echo >&2 $* "? \\c"
50                      else    echo >&2 -n $* "? "
51                      fi
52                      if read x
53                      then    case "$x"
54                              in [yYjJ]*)     return 0
55                              esac
56                      else    echo >&2
57                      fi
58                      return 1
59              fi
60              return 0
61      }'
62      
63      dup 'exec 3> $tmp'
64      
65      bundle() { # file...
66      (       for i
67          do    if [ -d $i ]
68              then    ask bundle $i || continue
69                  echo "ask unbundle $i && {"
70                  echo "[ -d $i ] || mkdir $i"
71                  bundle $i/*
72              elif [ -r $i ] && [ `tr -d '[ -~]\11\12' < $i |
73                   wc -c` = 0 ]
74              then    ask bundle $i || continue
75                  echo "ask unbundle $i && {"
76                  echo "sed 's/^    //' > $i << 'End of $i'"
77                  sed 's/^/    /' $i
78                  echo "End of $i"
79                  dup "wc >&3 $i"
80                  if [ "$has_x" ]
81                  then    [ -x $i ]
82                  else    [ `expr "\`ls -l $i\`" : '...x'` = 4 ]
83                  fi && echo "chmod +x $i"
84              else    continue
85              fi
86              [ -w $i ] || echo "chmod -w $i"
87              echo '}'
88          done
89      ) }
90      bundle $argv
91      
92      dup 'exec 3>&-'
93      echo 'diff >&2 -b - $tmp <<' "'End of wc'"
94      cat $tmp
95      echo 'End of wc'
96      dup exit=0


back | next | up | down | Inhalt | Uebungen | Complete | Kommentar


Created by unroff & hp-tools. © by Hans-Peter Bischof. All Rights Reserved (1997).

Last modified 03/July/97