initial add
This commit is contained in:
commit
1e414f35c9
6 changed files with 146 additions and 0 deletions
2
.windsurfrules
Normal file
2
.windsurfrules
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
1. No using strict
|
||||||
|
2. No using warnings
|
11
Makefile.PL
Normal file
11
Makefile.PL
Normal file
|
@ -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,
|
||||||
|
},
|
||||||
|
);
|
32
README.md
Normal file
32
README.md
Normal file
|
@ -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`
|
63
lib/History/SQLite.pm
Normal file
63
lib/History/SQLite.pm
Normal file
|
@ -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;
|
38
pshell.pl
Executable file
38
pshell.pl
Executable file
|
@ -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);
|
||||||
|
}
|
BIN
pshell_history.db
Normal file
BIN
pshell_history.db
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue