Linux/macOS: Retrieve RPMs from .sh file without running the script

Problem

Sometimes vendors ship their software as a single self-extracting .sh installer that contains multiple .rpm or other files inside.

Running the .sh directly might trigger installation logic you don’t want, so the challenge is: How can we safely unpack the RPMs without executing the script?

Solution

Most vendor installers provide built-in extraction flags that allow you to unpack it safely.

First, check whether your script supports extraction options:

  • Run it with --help.
  • Or open the file in a text editor (vi, vim, less) and search for the section that lists available options.
  • Look for keywords like --target, --noexec, or --keep.

    In my case, the script showed this usage block:

    $0 [options] [--] [additional arguments to embedded script]
    
    Options:
      --confirm             Ask before running embedded script
      --quiet               Do not print anything except error messages
      --noexec              Do not run embedded script
      --keep                Do not erase target directory after running
      --noprogress          Do not show the progress during decompression
      --nox11               Do not spawn an xterm
      --nochown             Do not give the extracted files to the current user
      --target dir          Extract directly to a target directory
                            (absolute or relative path)
      --tar arg1 [arg2 ...] Access the contents of the archive through tar
      --                    Pass following arguments to the embedded script
    
    

    The key flags here are:

    • --target -> specifies the output directory for extracted files
    • --noexec -> prevents the embedded installer logic from executing

    Here’s how I safely extracted the files from my .sh installer. You might need to create an extract directory before:

    $ sh flashgrid_cluster_node_update-25.5.89.70767.sh --target extract/ --noexec
    Creating directory extract/
    Verifying archive integrity... All good.
    Uncompressing update 100%
    

    Checking the number of files extracted, shows 46:

    $ ll extract/ | wc -l
    46
    

    /usr/local/Homebrew/Library/Homebrew/os/mac/version.rb:32:in `block in from_symbol’: unknown or unsupported macOS version: :dunno (MacOSVersionError)

    Problem:

    I am not able to install any software with brew on my Mac:

    brew install iostat-tool
    ...
    Traceback (most recent call last):
    	11: from /usr/local/Homebrew/Library/Homebrew/brew.rb:31:in `<main>'
    	10: from /usr/local/Homebrew/Library/Homebrew/brew.rb:31:in `require_relative'
    	 9: from /usr/local/Homebrew/Library/Homebrew/global.rb:80:in `<top (required)>'
    	 8: from /usr/local/Homebrew/Library/Homebrew/vendor/portable-ruby/2.6.3_2/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
    	 7: from /usr/local/Homebrew/Library/Homebrew/vendor/portable-ruby/2.6.3_2/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
    	 6: from /usr/local/Homebrew/Library/Homebrew/os.rb:7:in `<top (required)>'
    	 5: from /usr/local/Homebrew/Library/Homebrew/os.rb:43:in `<module:OS>'
    	 4: from /usr/local/Homebrew/Library/Homebrew/os/mac.rb:65:in `prerelease?'
    	 3: from /usr/local/Homebrew/Library/Homebrew/os/mac.rb:28:in `version'
    	 2: from /usr/local/Homebrew/Library/Homebrew/os/mac/version.rb:32:in `from_symbol'
    	 1: from /usr/local/Homebrew/Library/Homebrew/os/mac/version.rb:32:in `fetch'
    /usr/local/Homebrew/Library/Homebrew/os/mac/version.rb:32:in `block in from_symbol': unknown or unsupported macOS version: :dunno (MacOSVersionError)
    ...

    Solution:

    Reset brew and reinstall:

    brew update-reset
    
    ==> Fetching /usr/local/Homebrew...
    remote: Enumerating objects: 19541, done.
    remote: Counting objects: 100% (239/239), done.
    remote: Compressing objects: 100% (130/130), done.
    remote: Total 19541 (delta 118), reused 179 (delta 79), pack-reused 19302
    Receiving objects: 100% (19541/19541), 40.18 MiB | 32.55 MiB/s, done.
    Resolving deltas: 100% (9869/9869), done.
    From github.com:giobero/mydocflow
     * [new branch]          deployed-master   -> origin/deployed-master
     * [new branch]          dev               -> origin/dev
     * [new branch]          extjs4            -> origin/extjs4
     * [new branch]          extjs5            -> origin/extjs5
    ...
    
    
    ➜ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    
    ==> Checking for `sudo` access (which may request your password)...
    Password:
    ==> This script will install:
    /usr/local/bin/brew
    /usr/local/share/doc/homebrew
    /usr/local/share/man/man1/brew.1
    /usr/local/share/zsh/site-functions/_brew
    /usr/local/etc/bash_completion.d/brew
    /usr/local/Homebrew
    
    Press RETURN/ENTER to continue or any other key to abort:
    ==> /usr/bin/sudo /usr/sbin/chown -R mari:admin /usr/local/Homebrew
    ==> Downloading and installing Homebrew...
    remote: Enumerating objects: 59221, done.
    remote: Counting objects: 100% (10444/10444), done.
    remote: Compressing objects: 100% (49/49), done.
    remote: Total 59221 (delta 10405), reused 10419 (delta 10393), pack-reused 48777

    Make sure that brew was installed:

    brew doctor
    
    Please note that these warnings are just used to help the Homebrew maintainers
    ...
    
    Warning: Broken symlinks were found. Remove them with `brew cleanup`:
      /usr/local/share/zsh/site-functions/_brew_cask

    Run cleanup:

    brew cleanup

    Reinstall the target software:

    brew install iostat-tool
    
    ==> Tapping homebrew/cask
    Cloning into '/usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask'...
    remote: Enumerating objects: 706890, done.
    remote: Counting objects: 100% (250/250), done.
    remote: Compressing objects: 100% (169/169), done
    ...