File Bundles
August 14, 2015
It is sometimes convenient to package a group of files into a bundle, for transmission to a different computer or for archiving. Nowadays the most likely method involves tar and gzip, but in the past a “shell archive” was frequently used; the files, which are assumed to include only printable ascii characters, are collected into a single program file that can be executed to self-extract the included files.
Your task is to write a program that creates file bundles. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.
Python is the new shell..
This creates a self extracting py file:
code = """\ def write_file((filename, lines)): out = open(filename, 'w') for line in lines: out.write(line) out.close() files = [] """ def make_self_extracting_py(files): out = open('self_extracter.py', 'w') out.write(code) for i,filename in enumerate(files): content = open(filename).readlines() out.write("files.append(('{0}', {1}))".format(filename, content)) out.write("\n") out.write("map(write_file, files)") out.close() make_self_extracting_py(['text1.TXT', 'text2.TXT'])content of text1.TXT:
hello world
bye world
content of text2.TXT:
test with ‘qoutes’ and all other “stuf” should get ‘””” “””””IUYE754^!^#!%$#!%#*^ escaped..
result of above script is:
def write_file((filename, lines)): out = open(filename, 'w') for line in lines: out.write(line) out.close() files = [] files.append(('text1.TXT', ['hello world\n', 'bye world'])) files.append(('text2.TXT', ['test with \'qoutes\' and all other "stuf" should get \'"\'\'\'\' """""IUYE754^!^#!%$#!%#*^ escaped..'])) map(write_file, files)This can be run, result is original text files content again.
#!/usr/bin/env perl use strict; use warnings; sub make_shell_archive { my ($filenames) = @_; open my $outfile_fh, '>', 'extract_files.sh' or die "Unable to open 'extract_files.sh' for writing: $!"; foreach my $filename ( @$filenames ) { my $file_contents = do { open my $infile_fh, '<:encoding(UTF-8)', $filename or die "Unable to open file '$filename' for reading: $!"; <$infile_fh>; }; print {$outfile_fh} "echo -n '$file_contents' > $filename\n"; } close $outfile_fh; return; } make_shell_archive(\@ARGV);Two sample files: file1 and file2
file1 contents:
the quick brown fox jumped over the lazy dog
file2 contents:
foo bar baz quux
Usage: