peli has asked for the wisdom of the Perl Monks concerning the following question:

Hi all, I'm new to PerlMonks and hope you can help me with a problem.

I make a Swedish localization and Installers for a program for Mac and Win. This issue concerns Mac. After the user updates the app, it updates older files in User's directory when the app is launched. However, the app doesn't update these files in the Swedish version.

The solution to this was to make an addition to a post-install script that backs up the older User's files to the desktop directory (in case the user had made any changes to these files) and then erases them from the user's directory. In that case, the app copies the missing files from Library/Application Support directory to the User's/Library/Application Support directory.

For the previous version this addition worked but for the present, it doesn't. Something is wrong with the script and I can't figure it out. The output is that the script doesn't back up. Everything else in the script works.

The part of the script looks like this:

#!/usr/bin/perl use version $APPSUPPORT_PATH="/Library/Application Support/MakeMusic/Finale"; $PKG_RECORD_PATH="/Library/Application Support/MakeMusic/Finale/Instal +lerComponents/FinaleAppCore"; $PKG_RECORD_VERSION="25.0.0.0"; $PKG_RECORD_FAILURE_MESSAGE="Failed writing package record."; $REWIRE_SUPPORT_PATH="/Library/Application\ Support/Propellerhead\ Sof +tware/ReWire"; $REWIRE_TEMP_SUPPORT_PATH="/Library/Application\ Support/Propellerhead +\ Software/ReWire/Finale\ Install\ Temp"; $REGFILE_PATH="/Library/Application Support/MakeMusic/.regdata25.txt"; $REGFILE_FAILURE_MESSAGE="Failed writing version 25 file."; $QUICKLOOK_PATH="/Applications/Finale.app/Contents/Library/QuickLook/F +inale.qlgenerator"; $SPOTLIGHT_PATH="/Applications/Finale.app/Contents/Library/Spotlight/F +inale64.mdimporter"; ###################################################################### +########## # # Move Swedish User's files so app will update those files # ###################################################################### +########## ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time +); $year = $year + 1900; $mon = $mon + 1; $timeStampString = sprintf("%04u.%02u.%02u_%02u.%02u.%02u", $year, $mo +n, $mday, $hour, $min, $sec); $userFileBackupDir = $ENV{"HOME"}."/Desktop/Finale User Backup/".$PKG_ +RECORD_VERSION."_Backup_".$timeStampString; foreach $relativeFilePath (@MOVE_USER_FILES_FOR_UPDATES) { $existingPath = $ENV{"HOME"}."/".$relativeFilePath; print "checking: $existingPath\n"; if ( -e $existingPath ) { $backupPath = $userFileBackupDir."/".$relativeFilePath; makeDirAtPath_(parentDirOfPath_($backupPath)); print " moving: $backupPath\n"; rename($existingPath, $backupPath); } }

If nessecary, I'll add the rest of the script.

Thank's, I'm greatful for your help.

/peli

Replies are listed 'Best First'.
Re: Backup User's files
by kcott (Archbishop) on Jan 08, 2018 at 00:05 UTC

    G'day peli,

    Welcome to the Monastery.

    As ++karlgoethebier pointed out, and which you apparently didn't understand, you have a disembodied "use version" at the start of your code. You probably intended something else (see version) but didn't complete that line. Perl keeps reading until it finds a statement terminator (the semicolon, two lines later); it sees something like this:

    $ perl -MO=Deparse -e 'use version $X="x";' use version ($X = 'x'); -e syntax OK

    Your choice of using dynamic, instead of lexical, variables is questionable. As you've only provided part of your code, it's not possible to tell what effect that might have. I'd recommend using lexical variables; and using them in the smallest scope possible.

    You should always use the strict and warnings pragmata. See "perlintro - Perl introduction for beginners" for further discussion.

    You are using two different methods for handling whitespace in pathnames (i.e. "X X" and "X\ X"). Investigate whether that's causing any problems.

    It's hard to tell with only part of the code presented; however, it looks like you're performing various file operations without checking whether they worked as expected. Perl's builtin autodie pragma can probably do most, if not all, of this work for you; alternatively, write the code for these checks yourself.

    — Ken

      Thanks. And «disembodied "use version"» made my day. I'm still learning English at the monastery. Best regards, Karl

      «The Crux of the Biscuit is the Apostrophe»

      perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

      Before I do anything, I'll post the complete script.

      I must point out, I haven't the knowledge to write a script, so I didn't write this. This script is working except for the "Move user's files so app will update those files" section. If it can be improved, of course, it's good.

      #!/usr/bin/perl use version $APPSUPPORT_PATH="/Library/Application Support/MakeMusic/Finale"; $PKG_RECORD_PATH="/Library/Application Support/MakeMusic/Finale/Instal +lerComponents/FinaleAppCore"; $PKG_RECORD_VERSION="25.0.0.0"; $PKG_RECORD_FAILURE_MESSAGE="Failed writing package record."; $REWIRE_SUPPORT_PATH="/Library/Application\ Support/Propellerhead\ Sof +tware/ReWire"; $REWIRE_TEMP_SUPPORT_PATH="/Library/Application\ Support/Propellerhead +\ Software/ReWire/Finale\ Install\ Temp"; $REGFILE_PATH="/Library/Application Support/MakeMusic/.regdata25.txt"; $REGFILE_FAILURE_MESSAGE="Failed writing version 25 file."; $QUICKLOOK_PATH="/Applications/Finale.app/Contents/Library/QuickLook/F +inale.qlgenerator"; $SPOTLIGHT_PATH="/Applications/Finale.app/Contents/Library/Spotlight/F +inale64.mdimporter"; #APPPKG_PATH="/Applications/Finale.app/"; #AUDIO_COMPONENT_AMBIENCE="/Library/Audio/Plug-Ins/Components/Ambience +.component/"; #AUDIO_COMPONENT_SMSS="/Library/Audio/Plug-Ins/Components/SmartMusicSo +ftSynth.component/"; ###################################################################### +########## # # Move user's files so app will update those files # ###################################################################### +########## ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time +); $year = $year + 1900; $mon = $mon + 1; $timeStampString = sprintf("%04u.%02u.%02u_%02u.%02u.%02u", $year, $mo +n, $mday, $hour, $min, $sec); $userFileBackupDir = $ENV{"HOME"}."/Desktop/Finale User Backup/".$PKG_ +RECORD_VERSION."_Backup_".$timeStampString; foreach $relativeFilePath (@MOVE_USER_FILES_FOR_UPDATES) { $existingPath = $ENV{"HOME"}."/".$relativeFilePath; print "checking: $existingPath\n"; if ( -e $existingPath ) { $backupPath = $userFileBackupDir."/".$relativeFilePath; makeDirAtPath_(parentDirOfPath_($backupPath)); print " moving: $backupPath\n"; rename($existingPath, $backupPath); } } ###################################################################### +########## # # Create Desktop shortcut for Swedish Menu Commands Document # ###################################################################### +########## $swedishKeyboardDocPath1 = $APPSUPPORT_PATH."/Finale Extra/Finale Meny +kommandon.pdf"; $swedishKeyboardShortcut1 = $ENV{"HOME"}."/Desktop/Finale Menykommando +n.pdf"; if ( -e $swedishKeyboardDocPath1 ) { if ( -e $swedishKeyboardShortcut1 ) { unlink $swedishKeyboardShortcut1; } symlink($swedishKeyboardDocPath1, $swedishKeyboardShortcut1); } ###################################################################### +########## # # Create Desktop shortcut for Swedish Meta Tools Document # ###################################################################### +########## $swedishKeyboardDocPath2 = $APPSUPPORT_PATH."/Finale Extra/Finale Meta +verktyg.pdf"; $swedishKeyboardShortcut2 = $ENV{"HOME"}."/Desktop/Finale Metaverktyg. +pdf"; if ( -e $swedishKeyboardDocPath2 ) { if ( -e $swedishKeyboardShortcut2 ) { unlink $swedishKeyboardShortcut2; } symlink($swedishKeyboardDocPath2, $swedishKeyboardShortcut2); } # Create a Audio Units Support folder $auSupportFolderPath = $APPSUPPORT_PATH."/Audio Units Support"; $auSupportFolderMode = 0775; $appSupportFolderMode = 0775; if ( ! -d $auSupportFolderPath ) { if ( -e $auSupportFolderPath ) { # There's a file here instead of a folder -- delete it unlink $auSupportFolderPath; } makeDirAtPath_( $auSupportFolderPath ); } chmod $auSupportFolderMode, $auSupportFolderPath; chmod $appSupportFolderMode, $APPSUPPORT_PATH; # Check to see if the installer's rewire bundle needs to be installed. $rewire_bundle = $REWIRE_SUPPORT_PATH."/ReWire.bundle"; $rewire_temp_bundle = $REWIRE_TEMP_SUPPORT_PATH."/ReWire.bundle"; $copy_rewire_bundle = 0; if (-e $rewire_bundle) { $rewire_bundle_plist = $rewire_bundle."/Contents/Info.plist"; $rewire_temp_bundle_plist = $rewire_temp_bundle."/Contents/Inf +o.plist"; $current_version_string = `/usr/libexec/PlistBuddy -c "Print C +FBundleVersion" "$rewire_bundle_plist"`; $temp_version_string = `/usr/libexec/PlistBuddy -c "Print CFBu +ndleVersion" "$rewire_temp_bundle_plist"`; chomp $current_version_string; chomp $temp_version_string; my ($currentVer, $tempVer) = (version->parse($current_version_ +string), version->parse($temp_version_string)); if ($tempVer > $currentVer) { $copy_rewire_bundle = 1; `rm -rf "$rewire_bundle"`; } } else { $copy_rewire_bundle = 1; } if ($copy_rewire_bundle == 1) { `cp -R "$rewire_temp_bundle" "$rewire_bundle"`; } # remove the temp support folder in either case. `rm -rf "$REWIRE_TEMP_SUPPORT_PATH"`; # Create a "Favorite Plug-ins" folder if ( ( -d $APPSUPPORT_PATH."/Plug-ins" ) && ( ! -e $APPSUPPORT_PATH."/ +Plug-ins/Favorite Plug-ins" ) ) { makeDirAtPath_( $APPSUPPORT_PATH."/Plug-ins/Favorite Plug-ins" ); } # Finale activation file $regfileParentDirPath = parentDirOfPath_( $REGFILE_PATH ); $regfileParentDirMode = 0777; if ( ! -d $regfileParentDirPath ) { if ( -e $regfileParentDirPath ) { # There's a file here instead of a folder -- delete it unlink $regfileParentDirPath; } makeDirAtPath_( $regfileParentDirPath ); } chmod $regfileParentDirMode, $regfileParentDirPath; $regFileMode = 0666; if ( ! -e $REGFILE_PATH ) { open( REGFILE, ">$REGFILE_PATH" ) || die $REGFILE_FAILURE_MESSAGE. +"\n"; print REGFILE "[Sections]\n"; print REGFILE "XX=ABCD1234\n"; close( REGFILE ); } chmod $regFileMode, $REGFILE_PATH; # Reset the QuickLook Server and clients' generator cache if ( -e $QUICKLOOK_PATH ) { system ( "/usr/bin/qlmanage", "-r" ); } else { print "QuickLook plug-in not found at $QUICKLOOK_PATH"; } # Register our Spotlight component if ( -e $SPOTLIGHT_PATH ) { system ( "/usr/bin/mdimport", "-r", $SPOTLIGHT_PATH ); } else { print "Spotlight plug-in not found at $SPOTLIGHT_PATH"; } # Write a reciept for this component (for updaters) $pkgRecordParentDirPath = parentDirOfPath_( $PKG_RECORD_PATH ); $pkgRecordParentDirMode = 0775; if ( ! -d $pkgRecordParentDirPath ) { if ( -e $pkgRecordParentDirPath ) { # There's a file here instead of a folder -- delete it unlink $pkgRecordParentDirPath; } makeDirAtPath_( $pkgRecordParentDirPath ); } chmod $pkgRecordParentDirMode, $pkgRecordParentDirPath; $pkgRecordFileMode = 0665; if ( ! -e $PKG_RECORD_PATH ) { open( PKGRECFILE, ">$PKG_RECORD_PATH" ) || die $PKG_RECORD_FAILURE +_MESSAGE."\n"; print PKGRECFILE "$PKG_RECORD_VERSION\n"; close( PKGRECFILE ); } chmod $pkgRecordFileMode, $PKG_RECORD_PATH; exit 0; ###################################################################### +########## ###################################################################### +########## ###################################################################### +########## sub parentDirOfPath_ { local ( $path ) = @_; local @pathElements = split /\//, $path; pop @pathElements; return join '/',@pathElements; } sub makeDirAtPath_ { local ( $requestedDirPath, $toss ) = @_; if ( $requestedDirPath !~ m/^\// ) { print "FATALERROR: makeDirAtPath_ was not passed a full path ( +$requestedDirPath)"; exit 1; } local @dirPathElements = split '/', $requestedDirPath; local $dirPath = "/"; local $dirPathElement = ""; foreach $dirPathElement ( @dirPathElements ) { if ( length($dirPathElement) > 0 ) { $dirPath .= $dirPathElement; if ( ! -e $dirPath ) { mkdir( $dirPath ); } elsif ( ! -d $dirPath ) { print "FATALERROR: makeDirAtPath_ found non-dir path a +t $dirPath"; exit 1; } $dirPath .= "/"; } } if ( ! -d $requestedDirPath ) { print "FATALERROR: makeDirAtPath_ failed to create $requestedD +irPath"; exit 1; } } sub deleteFileOrDirAtPath_ { local ( $path ) = @_; if ( -e $path ) { system ( "rm", "-fdr", $path ); } if ( -e $path ) { return 0; } return 1; }

      /Peter

        the previous version this addition worked

        Can you post the code for that previous version ?
        The current version appears to be missing the end of this line

        use version

        and a line like this

        @MOVE_USER_FILES_FOR_UPDATES = ( <list of files> );

        poj
Re: Backup User's files
by karlgoethebier (Abbot) on Jan 07, 2018 at 17:10 UTC

    use version?

    «The Crux of the Biscuit is the Apostrophe»

    perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

      Ok.

      I'm sorry but I don't know what you mean? Can you be more specific?

        "...I don't know what you mean...more specific?"

        Sure. I guessed that you at least missed a semicolon which results in an syntax error - the message points to the wrong line as usual - if you run perl -c your_program.pl.

        Best regards, Karl

        «The Crux of the Biscuit is the Apostrophe»

        perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help