๐Ÿ›ก๏ธ SHC - Shell Script Compiler ๐Ÿš€

July 27, 2026 ยท View on GitHub

Generic Shell Script Compiler with Enhanced Security & Auditing

Latest Version Build Status ShellCheck Bash Maintenance Status License

GitHub Issues GitHub Pull Requests GitHub Stars GitHub Forks GitHub Contributors

Donate with PayPal Donate with Ko-fi Donate with QRIS Sponsor with GitHub Open Source Love

Empowering Developers โ€ข Securing Shell Scripts โ€ข Open Source Passion


๐Ÿ“– Overview

Shc takes a script, which is specified on the command line, and produces C source code. The generated source code is then compiled and linked to produce a stripped binary executable.

Insight: shc itself is not a compiler such as cc. It rather encodes and encrypts a shell script and generates C source code with an added expiration capability. It then uses the system compiler to compile a stripped binary which behaves exactly like the original script. Upon execution, the compiled binary will decrypt and execute the code with the shell -c option.

Note: The compiled binary will still be dependent on the shell specified in the first line of the shell code (i.e. shebang #!/bin/sh), thus shc does not create completely independent binaries.


โšก Installation

๐Ÿ› ๏ธ Building & Installing Locally

First, clone the repository and ensure you have the necessary packages for compiling:

# Clone the repository
git clone https://github.com/alsyundawy/shc.git
cd shc

# Install dependencies
sudo apt-get update
sudo apt-get install build-essential automake autoconf libtool

Then, compile and install from the source:

./autogen.sh
./configure
make
sudo make install

(Note: If make fails due to automake's version, ensure you have run ./autogen.sh before running the commands.)

๐Ÿง Debian GNU/Linux and Ubuntu Systems

sudo apt-get install shc

๐Ÿ“ฆ Ubuntu Systems (via PPA Repository)

sudo add-apt-repository ppa:alsyundawy/ppa
sudo apt-get update
sudo apt-get install shc

Prefer Pre-compiled Binaries? Download a compiled binary package from the Releases Page and copy the shc binary to /usr/bin and shc.1 to /usr/share/man/man1.


๐Ÿ’ป Usage

# General Usage
shc [options]

# Compile a script into a binary
shc -f script.sh -o binary

# Untraceable binary (prevents strace, ptrace, etc.)
shc -U -f script.sh -o binary  

# Untraceable binary, no root required (only sh scripts, no parameters)
shc -H -f script.sh -o binary  

๐Ÿ›ก๏ธ The Hardening Flag -H

This flag is currently in an experimental state and may not work on all systems. This flag only works for the default shell. For example, if you compile a bash script with the -H flag, the resulting executable will only work on systems where the default shell is bash. You may change the default shell, which generally is /bin/sh (often a symlink to bash or dash).

โš ๏ธ Notice: -H does not work with positional parameters (yet).


๐Ÿงช Testing

To run the test suite, simply use:

./configure
make
make test

Temporary directories are generated in ${TMPDIR:-/tmp}/shc.SHELL.OPT.XXXXXX (caps are replaced according to the test). When a test succeeds, the directory is removed; if it fails, it is kept to help with debugging.

Clean up test outputs manually with:

rm -rf ${TMPDIR:-/tmp}/shc.*

โš ๏ธ Known Limitations

  • SCRIPT Length: The _SC_ARG_MAX system configuration parameter limits the length of the arguments to the exec function. With standard options, this limits the maximum length of the runnable script of shc. However, you can now use the -P option which uses a pipe to circumvent this limitation.

โ— CHECK YOUR RESULTS CAREFULLY BEFORE USING โ—


๐Ÿ”’ CHANGES - Audit & Hardening

By HARRY DS ALSYUNDAWY - ALSYUNDAWY IT SOLUTION

๐ŸŒŸ LATEST: MON Jul 27 13:20:00 WIB 2026 - HARRY DS ALSYUNDAWY - ALSYUNDAWY IT SOLUTION

  • Fix: Fixed tcsh and rc test failures in test/ttest.sh by updating csh/tcsh shell pattern matching and handling rc positional arguments for -p option.
  • Fix: Formatted version_credits[] array in src/shc.c with tab indentation and joined split string literals in RTC[] array to eliminate compiler warnings.
  • Ci: Fixed GitHub Actions generate.yml workflow trigger typo (workflow_dispatch), autotools filter check, and added git diff check before git commit.
  • Ci: Fixed pre-commit.yml workflow logToCheckStyle required out parameter and pythonLocation context reference.
  • Ci: Updated .pre-commit-config.yaml to exclude config/ directory from beautysh/codespell, exclude test/ from cppcheck, and filter cpplint multiline comment/int warnings.
  • Qual: Updated pyproject.toml codespell ignore-words-list with domain words (ttest, indx, forceing) and added sscanf field width limits to test/scratch.c.
  • Ci: Fixed upload-artifact path pattern (/tmp/shc.*/*) and added if-no-files-found: ignore to .github/workflows/ci.yml.
  • Sec: Pinned third-party GitHub Actions (mdeweerd/logToCheckStyle and dorny/paths-filter) to full commit SHAs to resolve CodeQL actions/unpinned-tag security alert.
  • Docs: Updated README.md badge section: added Ko-fi, QRIS, styled PayPal, GitHub sponsor badges, and replaced deprecated Travis CI badge with GitHub Actions CI badge.
  • Qual: Resolved all cppcheck notices in src/shc.c by adding const qualifiers to pointer parameters (eval_shell, read_script, prnt_bytes, prnt_array), renaming local opts variable, reducing cnt variable scope, removing redundant continue/assignment, and adding inline suppressions for RC4 indx loops.
  • Qual: Fixed all C/C++ compiler and IDE linter semantic errors in src/shc.c: added explicit (char *) / (char **) casts to malloc/realloc, declared file as const char *, fixed const pointer discarding in eval_shell, updated prnt_bytes to accept const void *, initialized struct argv_builder fields, and joined split string literals in RTC[].
  • Qual: Cleared 100% of C compiler (-Wall -Wextra -Wpedantic -Wshadow -Wconversion -Wunreachable-code -Wuninitialized -Wstrict-prototypes) and IDE diagnostics in src/shc.c: initialized expdate=0, removed unreachable break statements after exit(0), removed unreachable return 1 in main(), refactored eval_shell() to use line_len and matches with %zus specifiers, added explicit sign and float conversion casts in random generators (rand_mod, noise, prnt_array), and added cppcheck suppressions.

Original Credit to @alsyundawy

MON Jul 27 12:43:31 WIB 2026 - HARRY DS ALSYUNDAWY - ALSYUNDAWY IT SOLUTION

  • Qual: Bumped package and internal source version to 4.0.9-Hardened-Audit-2026 across configure.ac, src/shc.c, README.md, and ChangeLog.
  • Fix: Resolved -Wformat-nonliteral compiler warning in eval_shell() by wrapping sscanf() with #pragma GCC diagnostic push/ignored/pop guards.
  • Fix: Added __attribute__((unused)) annotation to original_author struct declaration to fix -Wunused-const-variable compiler warning.
  • Docs: Updated version_credits[] array in src/shc.c to include email <alsyundawy@gmail.com> and website https://alsyundawy.com.
  • Style: Unified License entry into version_credits[] array and aligned all field labels to 19 characters for perfect colon (:) alignment in shc -V output.

Original Credit to @alsyundawy

FRI Jul 24 02:07:30 WIB 2026 - HARRY DS ALSYUNDAWY - ALSYUNDAWY IT SOLUTION

  • Feat: Added -V and --version options in src/shc.c to print version and exit, keeping POSIX getopt(3) compatibility without getopt_long.
  • Feat: Expanded shc -V and --version output to include original author, provider/maintainer, core collaborator, SHC contributors, repository URL, and audit hardening credit.
  • Sec: Hardened -P/-p pipe runtime by replacing predictable /tmp FIFO names with mkdtemp(3)-backed private temporary directories.
  • Sec: Added FIFO writer validation: checked open(2), closed descriptors, unlinked FIFO, and removed private temp directory after pipe delivery.
  • Fix: Replaced fixed 256-byte pipe command buffer with dynamic snprintf(NULL, 0, ...) allocation to prevent truncation.
  • Fix: Fixed SKIP_OPTS parsing in test/ttest.sh so empty option is not skipped when SKIP_OPTS is unset.
  • Qual: Added runtime PATH_MAX fallback and feature macro guards for mkdtemp(3), putenv(3), setenv(3), and strict builds in src/shc.c.
  • Qual: Bumped package and version to 5.0.8-Hardened-Audit-2026 in configure.ac, src/shc.c, README.md, docs/CHANGELOG.md, docs/DOCNOTE.md.
  • Qual: Declared newly used headers/functions in configure.ac.
  • Qual: Added stricter warning flags for normal maintainer builds in src/Makefile.am.
  • Docs: Documented corrected version credit in README.md, docs/CHANGELOG.md, docs/DOCNOTE.md to match ChangeLog collaboration notes.

Original Credit to @alsyundawy

๐ŸŒŸ LATEST: MON Jun 15 22:47:41 WIB 2026 - HARRY DS ALSYUNDAWY - ALSYUNDAWY IT SOLUTION

  • Sec: Hardened generated -P/-p pipe mode by replacing predictable /tmp/%08x FIFO names with mkdtemp(3) private temporary directories.
  • Sec: Added strict FIFO writer error handling: checked open(2), closed the descriptor, unlinked the FIFO, and removed the private temp directory.
  • Fix: Fixed test/ttest.sh SKIP_OPTS logic so the default empty option is not skipped accidentally when SKIP_OPTS is unset.
  • Fix: Replaced generated fixed-size char cmd[256] pipe command formatting with dynamically sized snprintf(NULL, 0, ...) allocation to avoid silent truncation.
  • Qual: Added generated runtime feature macro guards and PATH_MAX fallback for stricter compiler/libc compatibility.
  • Qual: Synchronized configure.ac and internal source version to 4.0.4-Hardened-Audit-2026.
  • Qual: Strengthened maintainer compile flags in src/Makefile.am with -Wpedantic and -Wformat=2.

Original Credit to @alsyundawy

๐ŸŒŸ LATEST: MON Jun 15 22:16:33 WIB 2026 - HARRY DS ALSYUNDAWY - ALSYUNDAWY IT SOLUTION

  • Sec: Replaced unsafe shell-command build execution with fork() + execvp() argv vectors for compiler and strip paths.
  • Sec: Replaced external chmod command with chmod(2) to avoid shell expansion and command parsing exposure.
  • Sec: Removed predictable /tmp/shc_x_<pid>.c and /tmp/shc_x_<pid>.so generation from -H runtime.
  • Fix: Fixed generated -H runtime buffer overflow in parent process-name reading with bounded fread() and explicit null termination.
  • Fix: Fixed fread() error handling in script loader so read failures are not silently treated as EOF.
  • Fix: Fixed unchecked allocation and overflow handling when generating output filename and expiration-message data.
  • Qual: Added safe argv-style parsing for CC, CFLAGS, LDFLAGS, and STRIP while preserving existing environment variable behavior.
  • Qual: Added strict POSIX feature declaration for C11 builds through Makefile.am.
  • Perf: Removed extra shell process creation during compiler, strip, and chmod execution paths.
  • Perf: Removed runtime helper compilation overhead from -H execution path.
  • Doc: Updated ChangeLog and README.md change notes by adding entries in the existing project format only.

Original Credit to @alsyundawy

๐ŸŒŸ LATEST: MON Jun 15 19:52:11 WIB 2026 - HARRY DS ALSYUNDAWY - ALSYUNDAWY IT SOLUTION

  • Feat: Added absolute out-of-the-box compiler support for modern & legacy shells: ksh88, ksh93, mksh, pdksh, fish, nu, pwsh, powershell, yash, osh, elvish.
  • Feat: Added global compatibility support for #!/usr/bin/env wrapper interpretation with complex parameter chaining.
  • Fix: Fixed critical bug where sscanf truncated whitespace-separated shebang options (e.g., env -S bash -e).
  • Fix: Fixed ARC4 encryption synchronization bug that passed raw binary ciphertexts to execvp wrappers causing abnormal behavior on env and sh variants.
  • Qual: Fixed internal state corruption and unsafe globbing mechanisms in test/match.
  • Qual: Hardened script headers using strict execution parameters (set -eu) across all POSIX payload testing scripts (test/match, test/pru.sh).
  • Qual: Replaced outdated and fragile string parsing echo with robust printf logic inside standard testing scripts.
  • Sec: Implement strict Shell options (set -Eeuo pipefail) & safe IFS parsing in test/ttest.sh.
  • Sec: Fix mktemp template vulnerabilities in test/ttest.sh to prevent predictable temp directories.
  • Qual: Add resilient OS-signal cleanup traps (EXIT, INT, TERM) to prevent orphan artifacts in test/ttest.sh.
  • Qual: Refactor arithmetic and shell evaluations to pass strict ShellCheck compliance (fixed SC2034, SC2145, SC2162, suppressed SC2329).
  • Qual: Enable strict error handling (set -e) in autogen.sh.
  • Qual: Fixed IDE C linting warnings in src/shc.c (removed unused headers, fixed array string missing comma, improved conditional statements).
  • Feat: Bumped internal version tag explicitly to '4.0.3 (Hardened Audit Edition - 15 Jun 2026)'.
  • Qual: Synchronized Autotools configure.ac to version 4.0.3-Hardened-Audit-2026.
  • Qual: Fixed massive Markdown linting errors (MD041, MD012, MD010) across ChangeLog and README.md.
  • Fix: Fixed double-percent formatting escape bug in shc.c causing sh: 1: %s: not found error during -H hardened compilation.
  • Fix: Added SKIP_OPTS support to test/ttest.sh; set SKIP_OPTS=-H in CI sanitize job to skip -H tests that are fundamentally incompatible with ASAN LD_PRELOAD injection.

Original Credit to @alsyundawy

๐Ÿ•’ LATEST: Aug 19 2024

  • Feat: Piping (-P, -p), with $0 forging (big scripts, perl, python) @fabio-brugnara.
  • Qual: Enhance tests (Check stderr, forging, tempdir, complex arguments), option SKIP (tests) @mdeweerd.
  • Qual: Add Github CI flox (build, run tests with(out) sanitizer, generate files) @mdeweerd.
  • Fix: Fix memory leaks in generated c-code @mdeweerd.
  • Fix: Fix memory leaks in generation c-code @ashamedbit #165
  • Fix: Fix static code checks/implement recommendations (prevent leaks, overflows) @mdeweerd.
  • Qual: Add static code checks, linting, code formatting @mdeweerd #162 #161
  • Doc: Improvements to the documentation @mdeweerd #163 #160
  • Doc: Add code block hinting for Ubuntu PPA install procedure lb803 #164
  • Feat: Remove ash dependency @dviererbe #167
  • Fix: Fix for script filenames with spaces/special characters @ergoucao #157.
  • Feat: Option -2 to use mmap2 @csersoft #132
  • Doc: Fix automatic hyperlinks by removing <> @learnpassword #148
  • Doc: Fix typo in usage @ghost #129
  • Fix: Fix strip in case of cross-compilation @embexus #125
  • Fix: Fix NULL-ptr dereference in shhl string @RKX1209 #83

Original Credit to @mdeweerd


๐Ÿค Contributing

We welcome your open-source passion! If you want to make pull requests, please target the master branch. The default branch is release, which should contain clean package files ready to be used.

๐Ÿ“ Documentation & Manuals

If you want to edit the manual, please edit the man.md file. The CI flow will automatically generate the other manual files from it. You can also generate these locally with the following commands (requires pandoc):

pandoc -s man.md -t man -o shc.1
# Also run this command to generate the HTML manual
pandoc -s man.md -t html -o man.html

โš™๏ธ Autotools

If you change anything related to autotools, ./autogen.sh should be run to regenerate the derived files. Again, the CI flow will generate these automatically. (You may need to pull after a push because of the changes committed by CI.)


๐Ÿ† Credits & Acknowledgements

This project is a hardened and heavily audited iteration built upon the incredible foundational work of neurobin. Huge thanks to the original author and the contributors of the neurobin/shc repository.


  1. Man Page
  2. Web Page

Developed with โค๏ธ & Passion by Open Source Community