A comprehensive Rust library and command-line tool for parsing and converting shell/bash scripts to other programming languages. This project provides a robust foundation for analyzing shell scripts, converting them to Perl, Rust, Python, and more, or building shell script analysis tools.
🌐 Try the Live Demo - Convert shell scripts to Perl, Rust, and other languages in your browser!
- Complete Lexer: Tokenizes shell/bash scripts with support for all major shell constructs
- AST Parser: Converts tokens into a structured Abstract Syntax Tree
- Multi-language Code Generation: Convert shell scripts to Perl, Rust, and Python
- Web Assembly Support: Run in the browser with a beautiful web interface
- Shell Constructs Support:
- Simple commands and arguments
- Pipelines and redirections
- Control flow (if/else, loops, functions)
- Variable expansions
- Command substitutions
- Arithmetic expressions
- File test operators
- Comments and whitespace
While Large Language Models (LLMs) like GPT-4 or Claude can translate shell scripts to other languages, this specialized transcoder offers several key advantages:
- Deterministic Output: Every conversion produces identical, predictable results
- No Hallucinations: Unlike LLMs, this tool won't invent non-existent functions or syntax
- Consistent Style: Maintains uniform code formatting and structure across all conversions
- Lightning Fast: Converts scripts in milliseconds without API calls or network latency
- Zero Cost: No API usage fees, token costs, or rate limits
- Offline Operation: Works completely offline without internet connectivity
- Deep Shell Knowledge: Built specifically for shell script semantics, not general text understanding
- Proper AST Parsing: Creates accurate Abstract Syntax Trees that preserve script logic
- Language-Specific Optimizations: Generates idiomatic code for target language
- CI/CD Ready: Can be integrated into build pipelines and automated workflows
- Library API: Provides programmatic access for embedding in other tools
- Batch Processing: Efficiently handles multiple files without API constraints
This tool is ideal for:
- Automated conversion pipelines
- Performance-critical applications
- Offline or air-gapped systems
- Consistent, repeatable conversions
git clone https://github.com/gmatht/debashc.git
cd debashc
cargo build --release
The debashc
binary provides several commands for analyzing and converting shell scripts:
# Tokenize a shell script
debashc lex "echo hello world"
# Parse a shell script to AST
debashc parse "ls | grep test"
# Parse a shell script from file
debashc file examples/simple.sh
# Convert shell script to Perl
debashc parse --perl "ls | grep test"
# Convert shell script to Rust
debashc parse --rust "ls | grep test"
# Convert shell script to Python
debashc parse --python "ls | grep test"
# Convert shell script file to Perl
debashc file --perl examples/simple.sh
# Interactive mode
debashc interactive
use debashc::{Lexer, Parser, Generator, RustGenerator, PythonGenerator};
// Tokenize a shell script
let input = "echo hello world";
let mut lexer = Lexer::new(input);
while let Some(token) = lexer.next() {
println!("Token: {:?}", token);
}
// Parse a shell script
let mut parser = Parser::new(input);
match parser.parse() {
Ok(commands) => {
for command in commands {
println!("Command: {:?}", command);
}
}
Err(e) => eprintln!("Parse error: {}", e),
}
// Convert to Perl
let mut generator = Generator::new();
let perl_code = generator.generate(&commands);
println!("Perl code: {}", perl_code);
Debashc includes a beautiful web interface powered by WebAssembly. You can run shell script conversions directly in your browser!
🌐 Live Demo - Try it now!
# Build the WASM target
./build-wasm.sh
# Or manually:
cargo install wasm-pack
wasm-pack build --target web --out-dir www/pkg
# Serve the web interface
cd www
python3 -m http.server 8000
# Then open http://localhost:8000 in your browser
The web interface provides:
- Real-time shell script tokenization
- AST visualization
- Conversion to Perl, Rust, and Python
- Interactive examples
- Responsive design for mobile and desktop
echo "Hello, World!"
Parses to a SimpleCommand
with name "echo" and arguments.
ls | grep "\.txt$" | wc -l
Parses to a Pipeline
with multiple commands connected by pipe operators.
if [ -f file.txt ]; then
echo "File exists"
else
echo "File does not exist"
fi
Parses to an IfStatement
with condition, then branch, and else branch.
function greet() {
echo "Hello, $1!"
}
Parses to a Function
with name and body.
The --perl
flag allows you to convert shell scripts to equivalent Perl code:
# Shell script
echo "Hello, World!"
# Convert to Perl
sh2perl parse --perl 'echo "Hello, World!"'
Output:
print "Hello, World!\n";
# Shell script
ls | grep "\.txt$" | wc -l
# Convert to Perl
sh2perl parse --perl 'ls | grep "\.txt$" | wc -l'
Output:
my $output;
$output = `ls`;
$output = `echo "$output" | grep "\.txt$"`;
print $output;
# Shell script
if [ -f file.txt ]; then
echo "File exists"
else
echo "File does not exist"
fi
# Convert to Perl
sh2perl parse --perl 'if [ -f file.txt ]; then echo "File exists"; else echo "File does not exist"; fi'
Output:
if (-f 'file.txt') {
print "File exists\n";
} else {
print "File does not exist\n";
}
# Shell script
mkdir newdir
cp file.txt newdir/
rm oldfile.txt
# Convert to Perl
sh2perl parse --perl 'mkdir newdir; cp file.txt newdir/; rm oldfile.txt'
Output:
mkdir('newdir') or die "Cannot create directory: $!\n";
use File::Copy;
copy('file.txt', 'newdir/') or die "Cannot copy file: $!\n";
unlink('oldfile.txt') or die "Cannot remove file: $!\n";
You can also convert entire shell script files to Perl:
# Create a shell script file
cat > example.sh << 'EOF'
#!/bin/bash
if [ -d /tmp ]; then
echo "Directory exists"
ls /tmp | head -5
else
echo "Directory does not exist"
fi
EOF
# Convert the file to Perl
sh2perl file --perl example.sh
Output:
if (-d '/tmp') {
print "Directory exists\n";
opendir(my $dh, '/tmp') or die "Cannot open directory: $!\n";
while (my $file = readdir($dh)) {
print "$file\n" unless $file =~ /^\.\.?$/;
}
closedir($dh);
} else {
print "Directory does not exist\n";
}
sh2perl/
├── src/
│ ├── lib.rs # Library entry point
│ ├── main.rs # Binary entry point
│ ├── lexer.rs # Tokenizer implementation
│ ├── parser.rs # Parser implementation
│ └── ast.rs # Abstract Syntax Tree definitions
├── examples/ # Example shell scripts
├── tests/ # Test files
└── Cargo.toml # Project configuration
The Lexer
struct provides tokenization of shell scripts:
pub struct Lexer {
tokens: Vec<(Token, usize, usize)>,
current: usize,
}
impl Lexer {
pub fn new(input: &str) -> Self;
pub fn next(&mut self) -> Option<&Token>;
pub fn peek(&self) -> Option<&Token>;
pub fn is_eof(&self) -> bool;
}
The Parser
struct converts tokens into an AST:
pub struct Parser {
lexer: Lexer,
}
impl Parser {
pub fn new(input: &str) -> Self;
pub fn parse(&mut self) -> Result<Vec<Command>, ParserError>;
}
The AST is composed of various command types:
SimpleCommand
: Basic commands with arguments and redirectionsPipeline
: Multiple commands connected by operatorsIfStatement
: Conditional executionWhileLoop
: Loop constructsForLoop
: Iteration over listsFunction
: Function definitionsSubshell
: Commands in subshells
Run the test suite:
cargo test
Run specific test categories:
cargo test lexer
cargo test parser
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Run the test suite
- Submit a pull request
This project is licensed under the GPLv3 License - see the LICENSE file for details.
- Support for more shell features (case statements etc.)
- Support for more builtins (build in awk, sed, sleep etc.)
- Shell script to other language converters
- Test more examples