#!/usr/bin/env perl ## envstore - save and load environment variables ## Copyright © 2009 by Daniel Friesel ## License: WTFPL use strict; use warnings; use 5.010; use Pod::Usage; use Storable 'nstore', 'retrieve'; my $store_file = $ENV{ENVSTORE_FILE} || "/tmp/envstore-$>"; my %store; my $action = shift; my $arg = shift; my $arg2 = shift; sub usage { pod2usage( -message => 'Syntax error', -exitval => 1, -verbose => 99, -sections => 'SYNOPSIS|DESCRIPTION', -output => \*STDERR, ); return; } sub check_store { my ($mode, $uid); if (-e $store_file) { ($mode, $uid) = (stat($store_file))[2,4]; } else { return 0; } if ($uid != $<) { print STDERR "envstore: store file is insecure (not owned by us)\n"; exit 1; } if (($mode & 0x00077) > 0) { print STDERR "envstore: store file is insecure (writable by group/others)\n"; exit 1; } return 1; } sub load_store { if (check_store) { %store = %{retrieve($store_file) || {}}; } return; } sub save_store { umask(0077); nstore(\%store, $store_file); return; } sub get_keyvalue { my ($key, $value) = @_; if (not defined($value)) { if (exists($ENV{$key})) { $value = $ENV{$key}; } else { print STDERR "No such parameter: $key (perhaps you forgot to export it?)\n"; exit(1); } } return($key, $value); } if ( not defined $action or ($action ~~ ['save', 'rm'] and not defined $arg) ) { usage; } load_store; given ($action) { when ('save') { my ($key, $value) = get_keyvalue($arg, $arg2); $store{$key} = $value; save_store; } when ('eval') { while (my ($key, $value) = each(%store)) { $value =~ s/'/'"'"'/g; print "export $key='$value'\n"; } } when (['show', 'list']) { while (my ($key, $value) = each(%store)) { printf("%-15s = %s\n", $key, $value); } } when ('rm') { delete($store{$arg}); save_store; } when ('clear') { unlink($store_file); } default { usage; } } __END__ =head1 NAME envstore - save and restore environment variables =head1 SYNOPSIS B I [ I ] =head1 DESCRIPTION envstore can save and restore environment variables, thus transferring them between different shells. I must be one of =over =item B Forget all stored variables =item B Produce shell code for evaluation, restoring all saved variables =item B I [I] Save I either with its current shell value or with I =item B List saved variables in better readable format =item B I Remove I from store =back =head1 ENVIRONMENT =over =item B The file in which the environment parameters are stored. By default F =back =head1 LIMITATIONS You should not store null bytes or similar extremely weird binary data. They might work fine, but there's a high chance that somewhere, something goes wrong and you start to lose bytes or get undefined behaviour. Also, since shells 'flatten' the input when using eval, newlines in variable values will be stored correctly, but silently dropped when loading the environment with eval. You can work around that by doing C<< envstore eval E $tmpfile; source $tmpfile >> or (in zsh) C<< source E(envstore eval) >>. =head1 AUTHOR B was written by Daniel Friesel Ederf@derf.homelinux.orgE Original idea and script by Maximilian Gass Emxey@ghosthacking.netE