Search code examples
batch-filegnupg

Batch scripting GPG decryption


I'm trying to write a Batch file to decrypt a folder of .gpg files that have all been encrypted with the same public key. This is what I have so far:

@ECHO off
SET outbound=C:\encrypted files
SET olddir=%CD%
SET password=correcthorsebatterystaple
CD /d %outbound%
DIR *.gpg /B > tmp.txt
FOR /F "tokens=*" %%F IN (tmp.txt) DO (
    ECHO %%F > tmplen.txt
    FOR %%L IN (tmplen.txt) DO (SET namelen=%%~zL)
    DEL tmplen.txt
    gpg --output %%F:~0, namelen-4 --batch --yes --passphrase %password% --decrypt %%F)
DEL tmp.txt
CD /d %olddir% 

Currently it just prints

usage: gpg [options] [filename]

This is my first time trying to write a Batch script, so I'm sure it's something simple.


Solution

  • The following should work:

    @ECHO off
    SET password=correcthorsebatterystaple
    PUSHD "C:\encrypted files"
    FOR /F "tokens=*" %%F IN ('DIR *.gpg /B') DO (
        gpg --output %%~nF --batch --yes --passphrase %password% --decrypt %%F)
    POPD
    

    Explanation:

    • PUSHD and POPD are used to temporarily manoeuvre into another directory;
    • there is no temporary text file required to hold the output of DIR, because FOR is also capable of parsing the output of a command (the set within IN () is enclosed with '' so it is interpreted as a command, not a file spec.);
    • to truncate the file extension (what you want to do with the second temporary file and the inner FOR loop, at least according to my interpretation), you just need to give the modifier ~n, in our situation %%~nF; your method did not work because:
      • you cannot do in-line maths like you tried by namelen-4 (you would need to use an interim variable together with SET /A for arithmetic operations, and also delayed expansion had to be active then);
      • the substring expansion like :~0,8 does not work with FOR variables (you would need an interim variable to do that, and again delayed expansion had to be active then);

    Addition:
    If the script has problems with whitespaces in the input file names, you may need to exchange the gpg command line with this:

    gpg --output "%%~nF" --batch --yes --passphrase %password% --decrypt "%%~F"
    

    The ~ modifiers remove potential surrounding double-quotes, so "%%~nF" and "%%~F" always enclose the file name with double-quotes. Notice that "%%F" could lead to double-double-quotes unintentionally...