commit 1e414f35c9413f8bb9b581bbed88661310bcf439 Author: kake26 Date: Sun Apr 13 21:37:36 2025 -0500 initial add diff --git a/.windsurfrules b/.windsurfrules new file mode 100644 index 0000000..0ea26aa --- /dev/null +++ b/.windsurfrules @@ -0,0 +1,2 @@ +1. No using strict +2. No using warnings diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..a838921 --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,11 @@ +use ExtUtils::MakeMaker; + +WriteMakefile( + NAME => 'pshell', + VERSION_FROM => 'lib/History/SQLite.pm', + PREREQ_PM => { + 'DBI' => 0, + 'DBD::SQLite' => 0, + 'Term::ReadLine' => 0, + }, +); diff --git a/README.md b/README.md new file mode 100644 index 0000000..af8009c --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# Perl Shell (pshell) + +A modular Perl shell with SQLite command history. + +## Features + +- Executes shell commands +- Logs all commands to SQLite database +- Modular design for easy extension + +## Installation + +1. Install dependencies: + ``` + cpanm --installdeps . + ``` + +2. Make the shell executable: + ``` + chmod +x pshell.pl + ``` + +3. Run the shell: + ``` + ./pshell.pl + ``` + +## Usage + +- Type commands as you would in a normal shell +- Type 'exit' to quit +- Command history is stored in `pshell_history.db` diff --git a/lib/History/SQLite.pm b/lib/History/SQLite.pm new file mode 100644 index 0000000..42706e2 --- /dev/null +++ b/lib/History/SQLite.pm @@ -0,0 +1,63 @@ +package History::SQLite; + +use DBI; + +sub new { + my ($class, %args) = @_; + + my $self = bless { + db_path => $args{db_path} || 'command_history.db' + }, $class; + + $self->_init_db; + + return $self; +} + +sub _init_db { + my ($self) = @_; + + my $dbh = DBI->connect("dbi:SQLite:dbname=$self->{db_path}", "", "", + { RaiseError => 1, PrintError => 0 }); + + $dbh->do(<<"SQL"); + CREATE TABLE IF NOT EXISTS command_history ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + command TEXT NOT NULL, + timestamp DATETIME DEFAULT CURRENT_TIMESTAMP + ) +SQL + + $dbh->disconnect; +} + +sub add { + my ($self, $command) = @_; + + my $dbh = DBI->connect("dbi:SQLite:dbname=$self->{db_path}", "", "", + { RaiseError => 1, PrintError => 0 }); + + $dbh->do("INSERT INTO command_history (command) VALUES (?)", undef, $command); + + $dbh->disconnect; +} + +sub get_all { + my ($self) = @_; + + my $dbh = DBI->connect("dbi:SQLite:dbname=$self->{db_path}", "", "", + { RaiseError => 1, PrintError => 0 }); + + my $sth = $dbh->prepare("SELECT command FROM command_history ORDER BY timestamp"); + $sth->execute; + + my @commands; + while (my $row = $sth->fetchrow_arrayref) { + push @commands, $row->[0]; + } + + $dbh->disconnect; + return @commands; +} + +1; diff --git a/pshell.pl b/pshell.pl new file mode 100755 index 0000000..61c61fd --- /dev/null +++ b/pshell.pl @@ -0,0 +1,38 @@ +#!/usr/bin/env perl + +use lib 'lib'; +use History::SQLite; +use Term::ReadLine; + +# Initialize command history +my $history = History::SQLite->new( + db_path => 'pshell_history.db' +); + +print "Perl Shell (pshell) - Type 'exit' to quit\n"; + +my $term = Term::ReadLine->new('pshell'); +$term->ornaments(0); + +# Load previous history +my @history = $history->get_all; +$term->addhistory($_) for @history; + +while (1) { + my $prompt = "pshell> "; + my $command = $term->readline($prompt); + + last unless defined $command; + chomp $command; + last if $command =~ /^exit$/i; + + # Skip empty commands + next unless length $command; + + # Save command to history + $history->add($command); + $term->addhistory($command); + + # Execute command + system($command); +} diff --git a/pshell_history.db b/pshell_history.db new file mode 100644 index 0000000..a24003c Binary files /dev/null and b/pshell_history.db differ