#!/usr/bin/env bash # --------------------------------------------------------------------------- # Script : txt2bin - Convert text files to self-displaying portable Linux binaries # Usage : txt2bin input.txt output_name # Release : 13 December 2025 # License : Blue Oak Model License # Copyright: 640kb.neocities.org # A fun little script based on the short story: The Council of Linux Greybeards # https://640kb.neocities.org/short.stories/shorts/the.council.of.linux.greybeards.html # See why this script exists: # https://640kb.neocities.org/apps/apps.free/txt2bin-why.html # --------------------------------------------------------------------------- # Features: # - Creates self-displaying files. 80-column or less input is recommended # - Great for self-displaying ASCII Art # - Preserves text layout with proper C string escaping # - Uses musl-gcc for smallest size, falls back to gcc -static # - Prevents accidental overwrites with safety prompts # --------------------------------------------------------------------------- if [[ "$1" == "-h" || "$1" == "--help" ]]; then echo echo " txt2bin converts text files into self-displaying portable Linux binaries" echo echo " Usage: txt2bin input.txt output_name (.c extension is automatically added)" echo echo " Creates: output_name.bin (a portable Linux executable)" echo echo " Examples:" echo " txt2bin infile.txt out.txt # Creates out.txt.bin (via out.txt.c)" echo " txt2bin art.txt picture # Creates picture.bin (via picture.c)" echo exit 0 fi if [ $# -ne 2 ]; then echo echo " Usage: txt2bin input.txt output_name" echo echo " For more information: txt2bin -h" echo exit 1 fi INPUT="$1" OUTPUT_BASE="$2" OUTPUT_C="${OUTPUT_BASE}.c" OUTPUT_BIN="${OUTPUT_BASE}.bin" if [ "$INPUT" = "$OUTPUT_C" ] || [ "$INPUT" = "$OUTPUT_BIN" ]; then echo echo " Error: Input file cannot have the same name as output files" echo " This would overwrite your source file!" echo exit 1 fi if [ -f "$OUTPUT_BIN" ]; then read -p "Warning: $OUTPUT_BIN already exists. Overwrite? (y/N) " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then echo " Aborted. Please choose a different output name." exit 1 fi rm -f "$OUTPUT_BIN" fi if [ -f "$OUTPUT_C" ]; then read -p "Warning: $OUTPUT_C already exists. Overwrite? (y/N) " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then echo "Aborted. Please choose a different output name." exit 1 fi rm -f "$OUTPUT_C" fi generate_c_source() { echo '#include ' echo '' echo 'int main(void) {' echo ' printf(' sed 's/["\]/\\&/g; s/^/ "/; s/$/\\n"/' "$INPUT" echo ' );' echo ' return 0;' echo '}' } compile_with_fallback() { local compiler="$1" local flags="$2" local method="$3" echo -n " Compiling with $compiler... " if $compiler $flags -o "$OUTPUT_BIN" "$OUTPUT_C"; then # echo " ($method)" echo echo " Created: $OUTPUT_BIN" echo " Size: $(stat -c%s "$OUTPUT_BIN") bytes" return 0 else echo " Failed" return 1 fi } echo echo " Generating C source..." generate_c_source > "$OUTPUT_C" || { echo "Error creating $OUTPUT_C"; exit 1; } echo " Created: $OUTPUT_C" echo if command -v musl-gcc >/dev/null 2>&1; then if ! compile_with_fallback "musl-gcc" "-static" "musl static"; then echo " musl-gcc failed, trying standard gcc..." if compile_with_fallback "gcc" "-static" "glibc static"; then echo " (Note: glibc static binaries are much larger)" fi fi elif compile_with_fallback "gcc" "-static" "glibc static"; then : else echo " Compilation failed: Could not create static binary" exit 1 fi echo echo " The Linux portable binary is ready..." echo " Run it: ./$OUTPUT_BIN" echo