russ@wpg.UUCP (russ) (02/15/88)
After hearing me brag about how great unix "tools" are for doing just about everything, a friend of mine asked me to duplicate a reel of nine-track tape that was estimated to contain app. 60 megs of data. Although I only have one nine track drive, I do have a cartridge streamer (20 megs) so I naively assumed that I could read and write the contents of the nine-track in 20 meg segments to three separate cartridge tapes and then concatenate the three cartridge tapes back onto a new reel of nine-track tape. I had figured that if 'dd' couldn't handle it, a simple-minded program (on the order of while getchar (putchar) would be able to do the job. Apart from my profound ignorance of whatever it is that passes for sentinel-like characters on tape devices, one of the things I didn't plan on was that the tape turned out to contain, not one big file, but rather a zillion or so small files that appear to range from two to seven blocks in length. I suppose I could repetitiously invoke 'dd' while keeping track of the total number of blocks, but I keep wondering what will happen if we get down to the end of a cartridge tape and then come across a five meg file. Any suggestions about how this thing could be handled "elegantly"? -- Russell Lawrence, WP Group, POB 306, Metairie, LA 70004 AT&T: +1 504 456 0001 COMPUSERVE: 72337,3261 UUCP: {philabs,hpda,nbires,amdahl,...}!uunet!wpg!russ
gwc@root.co.uk (Geoff Clare) (02/26/88)
In article <351@wpg.UUCP> russ@wpg.UUCP (russ) writes: > >After hearing me brag about how great unix "tools" are for doing just >about everything, a friend of mine asked me to duplicate a reel of >nine-track tape that was estimated to contain app. 60 megs of data. > >Although I only have one nine track drive, I do have a cartridge streamer >(20 megs) so I naively assumed that I could read and write the contents of >the nine-track in 20 meg segments to three separate cartridge tapes and >then concatenate the three cartridge tapes back onto a new reel of >nine-track tape. I had figured that if 'dd' couldn't handle it, a >simple-minded program (on the order of while getchar (putchar) would be >able to do the job. > >I suppose I could repetitiously invoke 'dd' while keeping track of the >total number of blocks, but I keep wondering what will happen if we get >down to the end of a cartridge tape and then come across a five meg file. > I thought I would knock up a shell script to do the job and mail it to Russ, but it took longer than I expected and when I was finished I thought "Hey, this is good stuff", so I'm going to post it in the hope that more people may find a use for it, or at least for some of the ideas in it. I should first issue a warning that this is totally untested, so apologies for any bugs in it, but I think the method should work. So here it is: ----------------------------- cut here ------------------------------- # shell script to copy mag tape to multiple cartridge volumes and back BLOCKSIZE=10k # mag tape block size required MAGTAPE=/dev/rmt8 # name of mag tape device CARTRIDGE=/dev/rct # name of cartridge device BLOCKSPERVOL=40000 # no. of 512 byte blocks to fill cartridge tape IFS="+$IFS" # add '+' to field seperator list to ease splitting of # dd block counts # write cartridges until fewer then requested no. of blocks are transferred blocks="$BLOCKSPERVOL" vol=1 dd if="$MAGTAPE" ibs="$BLOCKSIZE" | while test "$blocks" -eq "$BLOCKSPERVOL" do echo "insert cartridge $vol and press RETURN" read a </dev/tty a=`dd count="$BLOCKSPERVOL" of="$CARTRIDGE" 2>&1` echo $a set -- $a blocks=`expr $1 \+ $2` eval b"$vol"="$blocks" vol=`expr $vol \+ 1` done echo "insert blank mag tape to receive copy and press RETURN" read a # write back cartridges - no of blocks on each volume is in b$vol outvol=1 while test "$outvol" -lt "$vol" do echo >&2 "insert cartridge $outvol and press RETURN" read a eval blocks=\$b"$vol" echo >&2 "block count should be $blocks" dd count="$blocks" if="$CARTRIDGE" outvol=`expr $outvol \+ 1` done | dd obs="$BLOCKSIZE" of="$MAGTAPE" ----------------------------- cut here ------------------------------- -- Geoff Clare UniSoft Limited, Saunderson House, Hayne Street, London EC1A 9HH gwc@root.co.uk ...!mcvax!ukc!root44!gwc +44-1-606-7799 FAX: +44-1-726-2750
gwc@root.co.uk (Geoff Clare) (02/29/88)
When I actually got round to trying out the script I posted, there were a few problems with it I had not forseen (OK, I know I should have tried it *before* I posted it, but I was short of time, sorry). The main problem was that because the first loop was on the end of a pipe it was executed in a subshell, so all those carefully stored block counts were not available to the second loop. This has been cured by having the entire script from that point down executed as a subshell receiving the data from the pipe. Here is the updated version: ----------------------------- cut here ---------------------------- : # shell script to copy mag tape to multiple cartridge volumes and back BLOCKSIZE=10k # mag tape block size required MAGTAPE=/dev/rmt8 # name of mag tape device CARTRIDGE=/dev/rct # name of cartridge device BLOCKSPERVOL=40000 # no. of 512 byte blocks to fill cartridge tape IFS="+$IFS" # add '+' to field seperator list to ease splitting of # dd block counts # direct dd output into remainder of script as single subshell, instead of # just the first loop, to allow $b1 $b2 etc. to be accessed in the second loop dd if="$MAGTAPE" ibs="$BLOCKSIZE" | ( # write cartridges until < requested no. of blocks are transferred blocks="$BLOCKSPERVOL" vol=1 while test "$blocks" -eq "$BLOCKSPERVOL" do echo "insert cartridge $vol and press RETURN" read a </dev/tty a=`dd count="$BLOCKSPERVOL" of="$CARTRIDGE" 2>&1` echo "$a" set -- $a blocks=`expr $1 \+ $2` eval b"$vol"="$blocks" vol=`expr $vol \+ 1` done echo "insert blank mag tape to receive copy and press RETURN" read a </dev/tty # write back cartridges - no of blocks on each volume is in b$vol outvol=1 while test "$outvol" -lt "$vol" do echo >&2 "insert cartridge $outvol and press RETURN" read a </dev/tty eval blocks=\$b"$outvol" echo >&2 "block count should be $blocks" dd count="$blocks" if="$CARTRIDGE" outvol=`expr $outvol \+ 1` done | dd obs="$BLOCKSIZE" of="$MAGTAPE" ) ----------------------------- cut here ---------------------------- -- Geoff Clare UniSoft Limited, Saunderson House, Hayne Street, London EC1A 9HH gwc@root.co.uk ...!mcvax!ukc!root44!gwc +44-1-606-7799 FAX: +44-1-726-2750