#!/usr/bin/perl # apollias-zip-backup-script-for-linux-v2.pl # # by Apollia of Astroblahhh.Com. http://astroblahhh.com/ # # Completed 8/25/2011. # # Public domain. # # # This script makes it easy to make zipped backups of whatever files # and folders you want. After you get everything set up by following # the instructions below, you can run this script just by # double-clicking it. # # This script won't work in Windows. But, this script definitely # works in the Lucid Puppy 5.2 variety of Puppy Linux, and might # work (with slight modifications) in other kinds of Linux, if you # have the "zip" shell command available. # # If you don't have the RXVT terminal program (which is pre-installed # in Lucid Puppy 5.2 and other kinds of Puppy Linux), there are some # lines that you'll need to comment out which are in the section # after the "Stuff you can leave alone" section. # # http://www.murga-linux.com/puppy/viewtopic.php?p=479987 # (Topic: Lucid Puppy 5.2 Official Release JAN 5 2011) # # The instructions below usually assume that you're using Lucid Puppy # 5.2. # ########################################################################## # # # Instructions # # * If the name of this script file ends in ".txt", either remove # the ".txt" file extension, or change it to ".pl". # # (In Rox-Filer, you can rename files by right-clicking on them, going # to the "File '[name of the file you right-clicked on]'" menu, and # choosing Rename. Be careful to edit only the file name and not the # file path, because, annoyingly, the Rename function of Rox can do more # than just rename files - it can actually move files around if you change # the file path.) # # # * Open this script in a text editor. (In Lucid Puppy 5.2, by default, # there is an "edit" icon on the desktop which will open a text editor # named Geany.) # # # * If you don't have the RXVT terminal program (which is # pre-installed in Lucid Puppy 5.2 and other kinds of Puppy Linux), # there are some lines that you'll need to comment out which are # in the section after the "Stuff you can leave alone" section. # # You can comment out lines by putting a pound sign # at the beginning # of each line you want to comment out. # # # * Go the section titled "Variables you need (or might need) to change", # and follow the instructions there. # # # * You will most likely have to give this script Exec permissions to make # it possible to run this script just by double-clicking on it. # # In Lucid Puppy 5.2, if this script file currently has a title ending in # .txt (like apollias-zip-backup-script-for-linux.txt), and you have the file on # a drive in NTFS format (like most hard drives which have Windows # installed on them), you might be able to make the script # executable simply by renaming the file to something that doesn't end # in .txt, like apollias-zip-backup-script-for-linux.pl, or even a file name # without any filename extension such as .txt or .pl on the end. # # That works for files on my NTFS-format hard drive, but not with files # located in Puppy's RAM disk. # # # Another, more reliable way to grant Exec permissions to this script is: # # In Rox-Filer, right-click this simple-folder-opener.pl script, # go to the "File 'apollias-zip-backup-script-for-linux.pl'" menu, and choose # Properties. Then, put a check in the checkbox across from Owner # and under Exec, and click Close. # # # * Now, to run this script, you should be able to just double-click # on it. # # If it worked, an RXVT terminal window containing various informative text # should pop up, and your zip file should be at the folder path you # specified in $final_location_for_zip_file. # # # If no terminal window pops up, perhaps you put in a typo and it's # causing an error. If you would like to see what error is possibly # happening, you can run this script from a terminal window. # # In Rox-Filer, you can do that by going to the folder this script is # in and pressing `. (The backtick key. In case you rarely or never # use that and don't know where it is - it might be at the upper left # of your keyboard below the Esc key.) That will open an RXVT terminal # window. Then, type: # # perl apollias-zip-backup-script-for-linux.pl # # (or whatever the name of your script is) # # # Another reason this script might not work is: # # If you're using some other kind of Linux other than Lucid Puppy 5.2, # and Perl on your system is located somewhere other than # /usr/bin/perl, I'm guessing you might have to change the "shebang" # line at the top of the file to the correct path of Perl on your system. # # http://www.computerhope.com/jargon/s/shebang.htm # # # Oddly, if you compare a folder hosted on one kind of disk to the # exact same folder hosted on a different kind of disk, the amount # of disk space taken up by those folders may appear different. # # (In Rox-Filer, the amount of disk space taken up by a folder or file # is shown in the Size field of the Properties window, which you can # get to by right-clicking on the file, going to the "File '[name of # the file you right-clicked on]'" menu, and choosing "Properties".) # # So, if you wish to compare the disk space taken up by your original # folders and some unzipped backup copies of those folders, it's best # to compare copies of your folders that are both on the same kind of # volume, so you don't end up alarmed by seeing something like, one # of your folders in a TrueCrypt volume differs in size from a copy # of the exact same folder on Puppy's RAM disk. # # # * If you unzip your backup file using XArchive in Lucid Puppy 5.2, # it's good to either put your zip file in a new folder before # unzipping it, or, after you click Extract in XArchive, type a # new folder name in the window that pops up that says "Enter Directory # To Extract To" - since otherwise, the contents of the zip file will # end up possibly messily strewn about the folder the zip file is # currently in. ################################################################ # # Stuff you can leave alone # use Cwd 'abs_path'; $this_script_path=abs_path($0); $this_script_path=~s/ /\\ /g; $escaped_script_path=$this_script_path; $lastslashpos=rindex($this_script_path, "/"); $script_name=substr($this_script_path, $lastslashpos+1); print "Running $this_script_path...\n\n\n"; # # ################################################################ ############################################################################# # # This section of the script, which is only useful in Linux, # makes the script run in a window if double-clicked, if this # script file has Exec permissions, and you have the RXVT terminal # program. (If you're using Lucid Puppy 5.2 or probably various other # forms of Puppy Linux, you'll have RXVT). # # To give this script file Exec permissions in Lucid Puppy 5.2: # using the Rox-Filer file manager, right-click the script file, # and in the File: 'knt-html-to.ncd.pl' menu, select Properties. # Then, put a check in the checkbox across from Owner and under # Exec, and click Close. # # This entire section of code (consisting of the below 3 lines) # can be deleted or commented out if it's not working properly on # your system. if (!$ARGV[0]) # If this script is called with no arguments... { exec ("rxvt -rv +sb -sl 999 -title \"$script_name\" -e perl $escaped_script_path 1"); } # The exec command kills this script and runs the above shell command. # # The above shell command opens an RXVT terminal window, and runs this # Perl script again with one argument (just a meaningless 1 at the end), # which will enable the script to continue past this section. # # The point of this section is to make it so it's possible to read the # script's output without you having had to launch the script manually # from a command line. # # Otherwise, when you double-clicked on this script in your file manager # window, no output would be displayed. # # End of section of the script which makes the script run in a window # if double-clicked. # ########################################################################### ####################################################################### # # Variables you need (or might need) to change # # # # Both the below variables should be set to a folder path like # "/root/", and not a file path (like "/root/Backup.zip"). # # In Linux, all absolute paths begin with a slash. If a path # goes to a folder, it's good to also end the path with a slash # to show that it's a path to a folder. However, this script # will still work even if you forget the last slash. $temp_location_for_zip_file="/root/"; # I like to use a temporary location in Puppy's RAM disk, such as: # # /root/ # # That way, the script doesn't write anything to my physical # disk drive until the zip file is completely built. # # That's particularly useful with a Flash drive, because Flash # drives can only be used for a limited number of writes, # so it's good to minimize the number of writes you do. # # A quote from http://en.wikipedia.org/wiki/USB_flash_drive#Longevity - # # "Barring physical destruction of the drive, the memory # or USB connector of a flash drive will eventually fail. SLC # based memory is good for around 100,000 writes; more commonly # used MLC for around 10,000." $final_location_for_zip_file="/mnt/truecrypt20/Backups/"; $make_zip_file_in_temp_location_then_copy_to_final_location_for_zip_file="true"; # If true, the script builds the zip file at the path you provided in # $temp_location_for_zip_file, and when it's finished building that # zip file, it copies it to the path you provided in # $final_location_for_zip_file. # # If false, the script doesn't do anything with # $temp_location_for_zip_file and builds the zip file # at $final_location_for_zip_file. $file_manager_shell_command_to_use="rox"; $open_zip_file_folder_when_script_is_finished = "true"; # If true, the script will use the file manager shell command specified in # $file_manager_shell_command_to_use to open the folder the zip # file ended up in. $add_file_or_folder_names_to_zip_file_name="true"; # If false, the zip file name will be something like: # 2011_5_22-09,30,30--Backup.zip # # If true, and you've told the script to zip some files or # folders named (for example) "Saved Files" and "abdesk", the zip # file name will be something like: # # 2011_5_22-09,30,30--Backup--Saved Files--abdesk.zip # # If the zip's file name gets longer than 100 characters, # the script will crop the file name down to 100 characters. $use_full_paths="false"; # If you want to zip two different folders by the same name in two # different locations, like "/mnt/sda3/Saved Files" and # "/mnt/sda2/Saved Files", or two different files with the same name, # you'll need to change this to true. # # Otherwise, the contents of those two folders with the same # name will get mixed together in the zip file, and if both # folders happen to contain a file named (for example) A.txt, # only one A.txt file will be saved in the zip file - the other # will be overwritten. # # With this set to true, the full file path (like # "/mnt/sda3/Saved Files") will get stored, instead of just # "Saved Files". # # Be cautious about where you unzip a zip file that uses the full # file paths. If you unzip such a zip file to "/", then, the # unzipper software will try to unzip the files to their original # locations, which could be bad, if your unzipper software happens # to be willing to overwrite files already at those locations. @things_to_zip=( "/mnt/truecrypt1/xampp/htdocs/abdesk/", "/mnt/truecrypt2/Table/" ); # In the above array, put the paths of folders and/or files you # wish to zip. # # In Linux, all absolute paths begin with a slash. If the path # goes to a folder, it's good to also end the path with a slash # to show that it's a path to a folder. However, this script # will still work even if you forget the last slash. $halt_script_if_any_things_to_zip_dont_exist= "true"; # If true, the script will halt if it finds any of the files and # folders listed in @things_to_zip don't exist. # # If false, the script will just go ahead and create the zip file without the # missing files/folders. # # # End of variables you need (or might need) to change. # # Beyond this point, nothing else really needs to be changed. # ######################################################################## #################################################################### # # Variables, etc. you should probably leave alone # # my @nonexistent_paths; if ($make_zip_file_in_temp_location_then_copy_to_final_location_for_zip_file eq "true") { CheckForZipDestPathErrors("temp_location_for_zip_file"); $temp_location_for_zip_file=AddSlashIfNeeded($temp_location_for_zip_file); # Conveniently adds a slash to the end, if the user forgot. } CheckForZipDestPathErrors("final_location_for_zip_file"); $final_location_for_zip_file=AddSlashIfNeeded($final_location_for_zip_file); if ($make_zip_file_in_temp_location_then_copy_to_final_location_for_zip_file eq "true") { use File::Copy; } sub CheckForZipDestPathErrors { $var=$_[0]; if (!-e $$var) { print "Sorry, the folder provided in the $var variable doesn't exist. Please create it at $$var and run this script again."; PressReturnToCloseWindow(); } if (!-d $$var) { print "Sorry, the path provided in the $var variable leads to a file, not a directory. Please put a different path in $var, or change $$var to a directory, and run this script again."; PressReturnToCloseWindow(); } } sub AddSlashIfNeeded { $this_string=$_[0]; $lastchar = substr($this_string,length($this_string)-1,1); if ($lastchar ne "/") { $this_string .= "/"; } return $this_string; } @timeData = localtime(time); #print join(' ', @timeData); ($second, $minute, $hour, $dayOfMonth, $month, $yearOffset, $dayOfWeek, $dayOfYear, $daylightSavings) = localtime(time); $year = 1900 + $yearOffset; $month = $month + 1; $second = sprintf("%02d", $second); $minute = sprintf("%02d", $minute); $hour = sprintf("%02d", $hour); $zipfile_name=$year . "_" . $month . "_" . $dayOfMonth . "-" . $hour . "," . $minute . "," . $second . "--Backup"; # # End of variables, etc. you should probably leave alone # #################################################################### ################################################################### # # More stuff that doesn't need to be changed. # # foreach $thing_to_zip (@things_to_zip) { $len=length($thing_to_zip); $second_rightmost_slash_loc=rindex($thing_to_zip, "/", $len-2); $parentdirs=substr($thing_to_zip, 0, $second_rightmost_slash_loc+1); $file_or_folder_name=substr($thing_to_zip, $second_rightmost_slash_loc+1); $length_of_file_or_folder_name=length($file_or_folder_name); if (substr($file_or_folder_name, $length_of_file_or_folder_name-1, 1) eq "/") #If the last character is "/"... { chop($file_or_folder_name); #...get rid of it. } $this_full_path=$parentdirs . $file_or_folder_name; if (!-e $this_full_path) { push (@nonexistent_paths, $this_full_path); } else { $printable_list_of_things_to_zip=$printable_list_of_things_to_zip . "$thing_to_zip\n";; if ($add_file_or_folder_names_to_zip_file_name eq "true") { $zipfile_name = $zipfile_name . "--$file_or_folder_name"; } $parentdirs_and_file_or_folder_name{$this_full_path}=[$parentdirs, $file_or_folder_name]; } } if (@nonexistent_paths) { if ($halt_script_if_any_things_to_zip_dont_exist eq "true") { print "Nonexistent file(s) or folder(s) listed in things_to_zip array!\n\n"; foreach $nonexistent_path (@nonexistent_paths) { print " $this_full_path\n"; } print "\n\nHalting script. No zip file created."; PressReturnToCloseWindow(); } } if ($use_full_paths eq "true") { print "Using full paths for files in zip file."; } else { print "Using short paths for files in zip file."; } print "\n"; $length_of_zipfile_name=length($zipfile_name); if ($length_of_zipfile_name>96) { $zipfile_name=substr($zipfile_name, 0, 96); } $zipfile_name=$zipfile_name . ".zip"; if ($make_zip_file_in_temp_location_then_copy_to_final_location_for_zip_file eq "true") { $zip_file_path=$temp_location_for_zip_file . $zipfile_name; } else { $zip_file_path=$final_location_for_zip_file . $zipfile_name; } $final_zip_file_path=$final_location_for_zip_file . $zipfile_name; print "\n\nGoing to try to back up these paths:\n\n"; print $printable_list_of_things_to_zip; print "\n"; print "\n\nTrying to make zip...\n\n\n"; foreach $fullpath (keys %parentdirs_and_file_or_folder_name) { $array_reference = $parentdirs_and_file_or_folder_name{$fullpath}; @the_array=@$array_reference; $path=$the_array[0]; $file_or_folder=$the_array[1]; if ($use_full_paths eq "false") { chdir $path; $shell_command_line="zip -r \"$zip_file_path\" \"$file_or_folder\""; } elsif ($use_full_paths eq "true") { chdir "/"; $longfilepath=$path . $file_or_folder; $shell_command_line="zip -r \"$zip_file_path\" \"$longfilepath\""; } print "# $shell_command_line\n\n"; system ($shell_command_line); } print "\n\nHopefully backed up all these paths:\n\n"; print $printable_list_of_things_to_zip; print "\n"; $zip_file_path_to_display=$zip_file_path; if ($make_zip_file_in_temp_location_then_copy_to_final_location_for_zip_file eq"true") { if (!-e $final_zip_file_path) { if ( copy($zip_file_path, $final_zip_file_path)) { # We attempt the copy. # If it succeeded, we report that. print "\n\nSuccessfully copied temp zip to final location: $zip_file_path -> $final_zip_file_path\n"; $zip_file_path_to_display=$final_zip_file_path; } else { # If it failed, we report that. print "\n\nFailed to copy temp zip to final location: $zip_file_path -> $final_zip_file_path $!\n"; } } else { # If a file already exists at the destination... print "\nA file already exists at $final_zip_file_path - so didn't copy the temp zip from $zip_file_path to $final_zip_file_path.\n"; } } print "\n\nBackup finished!\n"; print "\nZip file at: $zip_file_path_to_display\n"; if ($open_zip_file_folder_when_script_is_finished eq "true") { $rightmost_slash_loc=rindex($zip_file_path_to_display, "/"); $zip_file_path_to_go_to=substr($zip_file_path_to_display, 0, $rightmost_slash_loc+1); $command_line="$file_manager_shell_command_to_use $zip_file_path_to_go_to"; print "\n\nOpening zip file location, $zip_file_path_to_go_to...\n # $command_line"; system ($command_line); } if (@nonexistent_paths) { print "\n\n\nNote: there were monexistent file(s) or folder(s) listed in things_to_zip array!\n\n"; foreach $nonexistent_path (@nonexistent_paths) { print " $this_full_path\n"; } if ($halt_script_if_any_things_to_zip_dont_exist eq "true") { print "\n\nHalting script. No zip file created."; PressReturnToCloseWindow(); } } PressReturnToCloseWindow(); # If you've rather have the rxvt window automatically disappear after the # script is finished running, comment out the previous line, and # uncomment the next 4 lines. # $secs=5; # print "\n\nThis window will automatically close in $secs seconds.\n\n\n"; # sleep $secs; # die; sub PressReturnToCloseWindow { print "\n\n\nYou can press Return (or Enter) to close this window.\n"; $wait_for_return = ; die; }