MC Press Online

Wednesday, May 24th

Last updateMon, 22 May 2017 4pm

You are here: Home ARTICLES Programming Programming - Other General TechTip: Use RPG and QShell for Zipping and Tarring Files

Programming / General

TechTip: Use RPG and QShell for Zipping and Tarring Files

Support MC Press - Visit Our Sponsors


Flexible Input, Dazzling Output with IBM i



Click for this Month's

Bookstore Special Deals

If you're putting data on the Web, you likely need to compress it first.


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, I have chosen to use the Java Archiving command JAR:


jar cfM /Public/ /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/ 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                                            


C                   EXSR      ZIP_IT                                           


C                   EXSR      TAR_IT                                           


C                   EVAL      *INLR = *ON                                      



C* SUBROUTINE: ZIP_IT                                                          



C     ZIP_IT        BEGSR                                                     

C                         EVAL      INFILENAME  = '/Public/test.xml'          

C                         EVAL      OUTFILENAME = '/Public/'      

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* SUBROUTINE: TAR_IT                                                          



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/


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


Archiving the XML files in the /Public folder into /Public/


jar cfM /Public/ /Public/*.xml


Archiving all of the files from the /Public folder into /Public/


jar cfM /Public/ /Public/

Thomas Snyder

Tom Snyder has a diverse spectrum of programming experience encompassing IBM technologies, open-source, Apple, and Microsoft and utilizing these technologies with applications on the server, on the web, or on mobile devices.


Tom has over 20 years experience as a software developer in various environments, primarily in RPG, Java, C#, and PHP and holds certifications in Java from Sun and PHP from Zend. Prior to software development, Tom worked as a Hardware Engineer at Intel and is a proud United States Naval Veteran Submariner who served aboard the USS Whale SSN638 submarine.


Tom is the best-selling author of Advanced Integrated RPG, which covers the latest programming techniques for RPG ILE and Java to utilize open-source technologies.


Originally from and currently residing in Scranton, Pennsylvania. Tom is currently involved in a Mobile Application Start-up company named JoltRabbit LLC.



MC Press books written by Thomas Snyder available now on the MC Press Bookstore.


Advanced, Integrated RPG Advanced, Integrated RPG

This book shows you how to take advantage of the latest technologies from within existing RPG applications.

List Price $79.95
Now On Sale