Sunteți pe pagina 1din 3

TechTip: Use RPG and QShell for Zipping and Tarring Files

As businesses provide more data to the Internet, one common administrative task required for preparing the data is to
compress the data into either a zip or a tar file.

The IBM i UNIX environment called QShell provides many capabilities, including the jar and tar commands used to
compress data. To enter QShell, go to the command line and type STRQSH to bring up a command line in the UNIX
environment. Here, you can try out your commands interactively to check the syntax and behavior of the commands
that you are executing. I primarily use QShell for operations that I want to perform in the IFS.

In this TechTip, I will compress a text file named test.xml that I have stored in a public folder off of the root directory
of the IFS.

Creating the TAR File

To compress the test.xml file into test_xml.tar, I have chosen to use the standard UNIX archiving command TAR:

tar cf /Public/test_xml.tar /Public/test.xml

• tar is the UNIX command.


• c indicates to create a new file.
• f indicates that the archive will be a file.
• /Public/test_xml.tar is the destination file name of the archive output (TOFILE in IBM lingo).
• /Public/test.xml is the source file name of the input file (FROMFILE in IBM lingo).

Creating the ZIP File

To compress the test.xml file into test_xml.zip, I have chosen to use the Java Archiving command JAR:

jar cfM /Public/test_xml.zip /Public/test.xml

• jar is the UNIX command.


• c indicates to create a new file.
• f indicates that the archive will be a file.
• M indicates that the manifest file should not be created. The JAR command's default behavior will
accommodate the jar archive format that would create a manifest file to determine the main class of the
Java archive. For the purpose of creating a pure zip archive, you would not want a manifest to be
created in the resulting archive file.
• /Public/test_xml.zip is the destination file name of the archive output (TOFILE in IBM lingo).
• /Public/test.xml is the source file name of the input file (FROMFILE in IBM lingo).

I strongly recommend that you test your intended archiving commands interactively in QShell before you attempt to
code it into your RPG program. This way, if you encounter any problems when running the RPG application, you will
know that the problem is in the RPG code, so you're not troubleshooting both the QShell command and the RPG
program at the same time.

Coding the QShell commands into RPG

Now that you have the syntax down and you've executed it interactively to make sure that it behaves the way that you
expect it to, you can code it into your RPG program to be executed. You do this by using the QCMDEXC command to
call the STRQSH command with the QShell command as the parameter.

D STRING S 1000A
D INFILENAME S 1000A
D OUTFILENAME S 1000A
D*
C EXSR ZIP_IT
C*
C EXSR TAR_IT
C*
C EVAL *INLR = *ON
C/EJECT
C**********************************************************************
C* SUBROUTINE: ZIP_IT
C* FUNCTION: EXECUTES HARD-CODED JAR COMMAND IN QSHELL.
C**********************************************************************
C ZIP_IT BEGSR
C EVAL INFILENAME = '/Public/test.xml'
C EVAL OUTFILENAME = '/Public/test_xml.zip'
C* ZIP THE XML FILE
C EVAL STRING = 'STRQSH CMD('
C + '''jar cfM '
C + %TRIM(OUTFILENAME) + ' '
C + %TRIM(INFILENAME)
C + ''')'
C Z-ADD 1000 STRLEN
C CALL 'QCMDEXC'
C PARM STRING
C PARM STRLEN 15 5
C ENDSR
C/EJECT
C**********************************************************************
C* SUBROUTINE: TAR_IT
C* FUNCTION: EXECUTES HARD-CODED TAR COMMAND IN QSHELL.
C**********************************************************************
C TAR_IT BEGSR
C EVAL INFILENAME = '/Public/test.xml'
C EVAL OUTFILENAME = '/Public/test_xml.tar'
C* TAR THE XML FILE
C EVAL STRING = 'STRQSH CMD('
C + '''tar cf '
C + %TRIM(OUTFILENAME) + ' '
C + %TRIM(INFILENAME)
C + ''')'
C Z-ADD 1000 STRLEN
C CALL 'QCMDEXC'
C PARM STRING
C PARM STRLEN 15 5
C ENDSR

Error When Submitting to Batch

OK, everything worked fine when I ran it interactively. So why does it crash when I submit it to batch? When you
submit the job to batch, you may get Message ID: RNQ0202, indicating that the call to QCMDEXC ended in error.

In our shop, we typically set up our job queues to run one job at a time to allow multiple jobs to be queued up and run
in sequential order. This common batch behavior can be a problem for applications that use QShell from RPG because
the job will spawn another job to do the QShell operations. Interactively, this isn't a problem because your interactive
subsystem allows multiple jobs to run concurrently. Otherwise, you would be the only one allowed on the system with
only one session allowed, and that can't work because you have to let the users on too. So more than one job can run
concurrently in the interactive subsystem.

To resolve this problem, I created a new subsystem for running these types of jobs in batch. When I used the Create
Subsystem Description (CRTSBSD) command, I set the MAXJOBS field to *NOMAX instead of the typical value of 1.
When I created the subsystem, I reused the original batch subsystem name of QBATCH and appended MAX to the end
of the new subsystem to become QBATCHMAX so that I remembered its behavior. I wouldn't want the system operator
to push a bunch of queued batch jobs over to this new subsystem that were depending on the previous job completing
before the next one started. You could end up with all of the jobs running concurrently and your bills being printed
before your account balances are updated!

Compressing Multiple Files into One Archive File

So far, we have compressed one file into an archive file to reduce the size of the original file, which reduces the time
that it takes to transfer the file across the network. You can also combine multiple files into one destination archive
file, which reduces the size and also organizes all of the files together. To do this, you simply keep adding the file
names to the end of the command.

Compressing an Entire Directory of Files into One Archive File

You can selectively add individual files to an archive by specifying each file that you wish to add, or you can use wild
cards to add all of the files within the specified directory that match the wild card criteria. If you wish to add every file
in the directory, you just specify the directory name as the source file. If you wish to only include the XML files, you
specify the directory with the *.xml wild card value.

Tar Examples:

Archiving files /Public/test1.xml, /Public/test2.xml, and /Public/test3.xml into /Public/test_xml.tar:

tar cf /Public/test_xml.tar /Public/test1.xml /Public/test2.xml /Public/test3.xml

Archiving the XML files into /Public/test_xml.tar:

tar cf /Public/test_xml.tar /Public/*.xml


Archiving all of the files from the /Public folder into /Public/test_xml.tar:

tar cf /Public/test_xml.tar /Public/

Zip Examples:

Archiving files /Public/test1.xml, /Public/test2.xml, and /Public/test3.xml into /Public/test_xml.zip:

jar cfM /Public/test_xml.zip /Public/test1.xml /Public/test2.xml /Public/test3.xml

Archiving the XML files in the /Public folder into /Public/test_xml.zip:

jar cfM /Public/test_xml.zip /Public/*.xml

Archiving all of the files from the /Public folder into /Public/test_xml.zip:

jar cfM /Public/test_xml.zip /Public/

S-ar putea să vă placă și