├── stdout └── stdout ├── mtrr └── mtrr ├── em └── em ├── forever └── forever ├── not └── not ├── summer └── summer ├── transpose ├── transpose-simple ├── transpose-par.pl ├── transposewrap.pl ├── transpose └── transpose.pod ├── rn └── rn ├── w4it-for-port-open └── w4it-for-port-open ├── swapout └── swapout ├── histogram ├── tests └── histogram ├── field └── field ├── README ├── Makefile ├── overlaydevice └── overlaydevice ├── goodpasswd └── goodpasswd ├── wssh ├── wssh~ └── wssh ├── neno └── neno ├── rand └── rand ├── zram-init └── zram ├── tracefile ├── tracefile └── tracefile.pod ├── reniced └── reniced ├── upsidedown └── upsidedown ├── blink └── blink └── timestamp ├── timestamp └── timestamp.1 /stdout/stdout: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | "$@" 2>&1 4 | -------------------------------------------------------------------------------- /mtrr/mtrr: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mtr -t -o "LSD NBAW" "$@" 4 | 5 | -------------------------------------------------------------------------------- /em/em: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | EMACS=`which emacs || which xemacs` 4 | 5 | exec $EMACS -nw "$@" 6 | -------------------------------------------------------------------------------- /forever/forever: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | while /bin/true 4 | do 5 | eval "$@" 6 | sleep 1 7 | done 8 | -------------------------------------------------------------------------------- /not/not: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if "$@"; then 4 | exit 1 5 | else 6 | exit 0 7 | fi 8 | 9 | 10 | -------------------------------------------------------------------------------- /summer/summer: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | my $sum = 0; 4 | 5 | while(<>) { 6 | $sum += $_; 7 | } 8 | print $sum,"\n"; 9 | -------------------------------------------------------------------------------- /transpose/transpose-simple: -------------------------------------------------------------------------------- 1 | Can it be done more simple? 2 | 3 | zcat D.gz | perl -ne 's/\s+/\n/g; open(OUT,">","out".(++$out)); print OUT' ; paste out* | pigz >Dt.gz 4 | -------------------------------------------------------------------------------- /rn/rn: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mkdir ~/.rm 2>/dev/null 4 | if mv "$@" ~/.rm ; then 5 | # OK 6 | true 7 | else 8 | mkdir -p ~/.rm/{1..10} 9 | mv "$@" ~/.rm/1 2>/dev/null || 10 | mv "$@" ~/.rm/2 2>/dev/null || 11 | mv "$@" ~/.rm/3 2>/dev/null || 12 | mv "$@" ~/.rm/4 2>/dev/null || 13 | mv "$@" ~/.rm/5 2>/dev/null || 14 | mv "$@" ~/.rm/6 2>/dev/null || 15 | mv "$@" ~/.rm/7 2>/dev/null || 16 | mv "$@" ~/.rm/8 2>/dev/null || 17 | mv "$@" ~/.rm/9 2>/dev/null || 18 | mv "$@" ~/.rm/10 19 | fi 20 | -------------------------------------------------------------------------------- /w4it-for-port-open/w4it-for-port-open: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | HOST=$1 4 | PORT=$2 5 | 6 | NC=$( which nc ) 7 | 8 | usage () { 9 | echo "Usage:" 10 | echo " $0 host [port]" 11 | echo " port defaults to 22 (ssh)" 12 | exit 1 13 | } 14 | 15 | print_not_reachable () { 16 | echo -n . 17 | } 18 | 19 | is_port_open () { 20 | $NC -z -w 2 $HOST $PORT 2>&1 21 | return $? 22 | } 23 | 24 | if [ -z "$HOST" ] ; then 25 | usage 26 | fi 27 | if [ -z "$PORT" ] ; then 28 | PORT=22 29 | fi 30 | if [ -z "$NC" ] ; then 31 | echo "Error, 'nc' not installed." 32 | exit 2 33 | fi 34 | 35 | while ! is_port_open ; do 36 | sleep 1 37 | print_not_reachable 38 | done 39 | echo 40 | -------------------------------------------------------------------------------- /swapout/swapout: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | $timeout = shift || 10; 4 | 5 | $total=10000000; 6 | 7 | my $giga=2**30; 8 | my $forks=1; 9 | 10 | do{ 11 | $start=time; 12 | $total=int(1+$total*1.03); 13 | $missing=$total-$sofar; 14 | $buf{$forks}{$total}="x"x$missing; 15 | $sofar=$total; 16 | $timediff=time-$start; 17 | print "Chunk size: $missing Time for swapping: $timediff seconds. Total memory used: $total\n"; 18 | if($total > $forks * $giga) { 19 | if($pid=fork()) { 20 | print "child spawn ",$forks,"\n"; 21 | wait; 22 | print "child exit ",$forks,"\n"; 23 | } else { 24 | $buf{$forks}=1; 25 | $forks++; 26 | } 27 | } 28 | } until ($pid or $timediff>$timeout); 29 | print "exit ",$forks,"\n"; 30 | -------------------------------------------------------------------------------- /transpose/transpose-par.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | #!/usr/local/bin/parallel --shebang-wrap --pipe --block 10m -k --files /usr/bin/perl | xargs paste 4 | 5 | use Text::CSV; 6 | use File::Temp qw(tempfile tempdir); 7 | 8 | my $csv; 9 | my (@table); 10 | my $first_line = 1; 11 | my $col = 0; 12 | while(my $l = <>) { 13 | if($first_line) { 14 | my $csv_setting = guess_csv_setting($l); 15 | $csv = Text::CSV->new($csv_setting) 16 | or die "Cannot use CSV: ".Text::CSV->error_diag (); 17 | $first_line = 0; 18 | } 19 | if(not $csv->parse($l)) { 20 | die "CSV has unexpected format"; 21 | } 22 | # append to each row 23 | my $row = 0; 24 | 25 | for($csv->fields()) { 26 | $table[$row][$col] = defined($_) ? $_ : ''; 27 | $row++; 28 | } 29 | $col++; 30 | } 31 | 32 | print map { join("\t",@$_),"\n" } @table; 33 | 34 | sub guess_csv_setting { 35 | # Based on a single line guess the csv_setting 36 | return { binary => 1 }; 37 | } 38 | -------------------------------------------------------------------------------- /histogram/tests: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "## pre space, decimal" 4 | (echo ' 8.999 otte'; echo '16.999 seksten') | histogram 5 | (echo ' 8.999,otte'; echo '16.999,seksten') | histogram --input v,h 6 | 7 | echo "## two decimal, only values" 8 | seq 1 .09 2 | histogram --input v 9 | 10 | echo "## 1 2 3 command line" 11 | histogram 1 2 3 12 | 13 | echo "## a:1 b:2 c:3 command line" 14 | histogram a:1 b:2 c:3 15 | echo "## a 1 b 2 c 3" 16 | (echo a 1; echo b 2; echo c 3) | histogram 17 | echo "## a 1 b 2 c 3" 18 | (echo "a 1"; echo b 2; echo c 3) | histogram 19 | 20 | echo "## 1,a 2,b command line" 21 | histogram 1,a 2,b 22 | echo "## 1 2 3 4 command line" 23 | histogram 1 2 3 4 24 | echo "## a 1 b 2 c 3 command line - not ideal" 25 | histogram a 1 b 2 c 3 26 | echo '## "a a":1 b:2 c:3 command line' 27 | histogram "a a":1 b:2 c:3 28 | echo "## null input" 29 | histogram {$#F}} = eval $fields; 31 | } 32 | print join(" ",@F[@{$Calc::fields->{$#F}}]),"\n"; 33 | } else { 34 | print join(" ",@F[@fields]),"\n"; 35 | } 36 | 37 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 2 | 3 | MOVED TO https://gitlab.com/ole.tange/tangetools 4 | 5 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 6 | 7 | Tools developed by Ole Tange . 8 | 9 | Probably not useful for you, but then again you never now. 10 | 11 | em - Force emacs to run in terminal. Use xemacs if installed. 12 | 13 | field - Split on space. Give the given field number. Support syntax 1-3,6- 14 | 15 | forever - Run the same command or list of commands every second. 16 | 17 | neno - No error no output. Only print STDERR and STDOUT if the command fails. 18 | 19 | rand - Generate (pseudo-)random data 20 | 21 | reniced - Renice all commands running more than 1 CPU minute unless they are niced or whitelisted. 22 | 23 | rn - Move file(s)/dir(s) to ~/.rm/ (wastebasket). 24 | 25 | stdout - Redirect both STDERR and STDOUT to STDOUT. 26 | 27 | tracefile - List files being accessed by program. 28 | 29 | w4it-for-port-open - Block until the given port opens on a given host. 30 | 31 | wssh - Shorthand for w4it-for-port-open $host 22; ssh $host 32 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: blink/blink.1 histogram/histogram.1 upsidedown/upsidedown.1 tracefile/tracefile.1 timestamp/timestamp.1 rand/rand.1 2 | 3 | blink/blink.1: blink/blink 4 | pod2man blink/blink > blink/blink.1 5 | 6 | histogram/histogram.1: histogram/histogram 7 | pod2man histogram/histogram > histogram/histogram.1 8 | 9 | rand/rand.1: rand/rand 10 | pod2man rand/rand > rand/rand.1 11 | 12 | timestamp/timestamp.1: timestamp/timestamp 13 | pod2man timestamp/timestamp > timestamp/timestamp.1 14 | 15 | tracefile/tracefile.1: tracefile/tracefile.pod 16 | pod2man tracefile/tracefile.pod > tracefile/tracefile.1 17 | 18 | upsidedown/upsidedown.1: upsidedown/upsidedown 19 | pod2man upsidedown/upsidedown > upsidedown/upsidedown.1 20 | 21 | wssh/wssh.1: wssh/wssh 22 | #pod2man wssh/wssh > wssh/wssh.1 23 | 24 | install: 25 | mkdir -p /usr/local/bin 26 | parallel eval ln -sf `pwd`/*/{} /usr/local/bin/{} ::: blink reniced em field forever neno rn stdout tracefile w4it-for-port-open upsidedown histogram goodpasswd mtrr not summer timestamp transpose wssh aptsearch rand 27 | mkdir -p /usr/local/share/man/man1 28 | parallel ln -sf `pwd`/{} /usr/local/share/man/man1/{/} ::: */*.1 29 | -------------------------------------------------------------------------------- /overlaydevice/overlaydevice: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | start() { 4 | DEVICE=$1 5 | BASE=$(basename $DEVICE) 6 | OVERLAY=overlay-$BASE 7 | 8 | SIZE=$(blockdev --getsize $DEVICE) 9 | BYTESIZE=$(blockdev --getsize64 $DEVICE) 10 | 11 | # Create sparse file as big as possible 12 | OVLSIZE=$BYTESIZE 13 | while ! truncate -s${OVLSIZE} $OVERLAY; do 14 | echo $OVLSIZE failed 15 | OVLSIZE=$(( OVLSIZE/2 )) 16 | done 17 | 18 | if ! LOOPDEV=$(losetup --show -f -- $OVERLAY); then 19 | LOOPS=$(ls /dev/loop* | wc -l) 20 | mknod -m 660 /dev/loop$LOOPS b 7 $LOOPS 21 | LOOPDEV=$(losetup --show -f -- $OVERLAY) 22 | fi 23 | 24 | echo 0 $SIZE snapshot $DEVICE $LOOPDEV P 8 | dmsetup create $BASE 25 | echo Overlay device: /dev/mapper/$BASE 26 | echo Overlay file: $OVERLAY 27 | echo Stop with: 28 | echo dmsetup remove $BASE; rm $OVERLAY 29 | echo losetup -d $LOOPDEV 30 | } 31 | 32 | stop() { 33 | DEVICE=$1 34 | BASE=$(basename $DEVICE) 35 | OVERLAY=overlay-$BASE 36 | dmsetup remove $BASE 37 | # Find the loop device with $OVERLAY and stop it 38 | losetup -d $(losetup -j $OVERLAY) 39 | rm $OVERLAY 40 | } 41 | 42 | start $1 43 | 44 | 45 | -------------------------------------------------------------------------------- /goodpasswd/goodpasswd: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | # This program generates passwords that: 4 | # 5 | # * are hard to guess 6 | # * will be displayed unambigously in any (normal) font 7 | # * will survive being passed through a bad fax machine 8 | # * will survive being passed through handwriting 9 | # * has UPPER lower number and sign 10 | # 11 | # Too close: B8 cC g9 6G kK lI l1 oO O0 pP sS uU vV xX zZ Z2 ,. :; `' S5 12 | # Causes problems in URLs: @/: 13 | # Causes problems in shell: ! " # $ & ( ) [ ] { } ? | < > \ * = 14 | # SQL uses: % for wildcard 15 | # Hard to type: ^ ~ ¨ ¤ § ½ æ ø å Æ Ø Å 16 | # Never 2 same chars next to eachother. (--) is bad 17 | # Do not start with '-' or '+' as that looks like an (long) option 18 | # 19 | # US-kbd: ~!@#$%^&*()_+ [] {} ;'\ :"| < > ,./ <>? 20 | # DK-kbd: §!"#¤%&/()=?` å" Å^ æø' ÆØ* < > ,.- ;:_ 21 | # Common: ! # % < > ,. 22 | 23 | my $pw; 24 | my @chars=split //, 'abdefhijmnqrtyADEFHJLMNQRTY347+-'; 25 | do { 26 | $pw = ""; 27 | for (1..12) { 28 | $pw .= $chars[rand $#chars+1] 29 | } 30 | } while (($pw =~ /^[+-]/ or $pw =~ /(.)\1/) or 31 | not($pw =~ /[A-Z]/ and 32 | $pw =~ /[a-z]/ and 33 | $pw =~ /[0-9]/ and 34 | $pw =~ /[^a-zA-Z0-9]/)); 35 | 36 | print "$pw\n"; 37 | -------------------------------------------------------------------------------- /wssh/wssh~: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | my @argv = @ARGV; 4 | 5 | use Getopt::Long; 6 | 7 | sub options_hash { 8 | # Returns a hash of the GetOptions config 9 | return 10 | ("1|2|4|6|A|a|C|f|g|K|k|M|N|n|q|s|T|t|V|v|X|x|Y|y" => \$opt::one, 11 | "b|c|D|E|e|F|I|i|L|l|m|O|o|p|Q|R|S|W|w=s" => \$opt::arg, 12 | ); 13 | } 14 | 15 | sub get_options_from_array { 16 | # Run GetOptions on @array 17 | # Returns: 18 | # true if parsing worked 19 | # false if parsing failed 20 | # @array is changed 21 | my ($array_ref, @keep_only) = @_; 22 | if(not @$array_ref) { 23 | # Empty array: No need to look more at that 24 | return 1; 25 | } 26 | # A bit of shuffling of @ARGV needed as GetOptionsFromArray is not 27 | # supported everywhere 28 | my @save_argv; 29 | my $this_is_ARGV = (\@::ARGV == $array_ref); 30 | if(not $this_is_ARGV) { 31 | @save_argv = @::ARGV; 32 | @::ARGV = @{$array_ref}; 33 | } 34 | # If @keep_only set: Ignore all values except @keep_only 35 | my %options = options_hash(); 36 | if(@keep_only) { 37 | my (%keep,@dummy); 38 | @keep{@keep_only} = @keep_only; 39 | for my $k (grep { not $keep{$_} } keys %options) { 40 | # Store the value of the option in @dummy 41 | $options{$k} = \@dummy; 42 | } 43 | } 44 | my $retval = GetOptions(%options); 45 | print @ARGV; 46 | if(not $this_is_ARGV) { 47 | @{$array_ref} = @::ARGV; 48 | @::ARGV = @save_argv; 49 | } 50 | return $retval; 51 | } 52 | 53 | #w4it-for-port-open $1 22 54 | 55 | 56 | -------------------------------------------------------------------------------- /neno/neno: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # NAME 4 | # neno - no error no output 5 | # 6 | # SYNOPSIS 7 | # neno command1 [\; command2 ...] 8 | # 9 | # DESCRIPTION 10 | # neno will print the output from both standard output and 11 | # standard error if the composed command returns an error. If the 12 | # composed command returns true, the output will be ignored. 13 | # 14 | # This is useful for cron jobs where you only want output if it 15 | # failed. 16 | # 17 | # AUTHOR 18 | # Ole Tange 19 | # 20 | # COPYRIGHT 21 | # Copyright © 2012 Free Software Foundation, Inc. License 22 | # GPLv3+: GNU GPL version 3 or later 23 | # . This is free software: you 24 | # are free to change and redistribute it. There is NO WARRANTY, 25 | # to the extent permitted by law. 26 | 27 | print() { 28 | cat $TMP/stderr >&4 29 | cat $TMP/stdout >&3 30 | } 31 | 32 | cleanup() { 33 | rm -rf $TMP 34 | return $? 35 | } 36 | 37 | control_c() { 38 | # Run if user hits control-C 39 | # >&4 is the non-redirected stderr 40 | echo >&4 41 | print 42 | echo -en "\n$0: CTRL-C hit: Exiting.\n" >&4 43 | cleanup 44 | exit $? 45 | } 46 | 47 | # trap keyboard interrupt (control-c) 48 | trap control_c SIGINT 49 | 50 | TMP=$(mktemp -d /tmp/no-error.XXXXX) 51 | exec 3>&1 4>&2 52 | eval $* 2>$TMP/stderr >$TMP/stdout 53 | ERROR=$? 54 | if [ $ERROR == 0 ] ; then 55 | # skip 56 | true 57 | else 58 | print 59 | fi 60 | cleanup 61 | exit $ERROR 62 | -------------------------------------------------------------------------------- /wssh/wssh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use Getopt::Long; 4 | 5 | my @argv = @ARGV; 6 | get_options_from_array(\@ARGV,[]); 7 | my $host = shift @ARGV; 8 | @ARGV=("ssh",@argv); 9 | $host =~ s/.*\@//; 10 | print $host; 11 | system("w4it-for-port-open $host 22"); 12 | exec @ARGV; 13 | 14 | sub options_hash { 15 | # Returns a hash of the GetOptions config 16 | return 17 | ("1|2|4|6|A|a|C|f|g|K|k|M|N|n|q|s|T|t|V|v|X|x|Y|y" => \$opt::one, 18 | "b|c|D|E|e|F|I|i|L|l|m|O|o|p|Q|R|S|W|w=s" => \$opt::arg, 19 | ); 20 | } 21 | 22 | sub get_options_from_array { 23 | # Run GetOptions on @array 24 | # Returns: 25 | # true if parsing worked 26 | # false if parsing failed 27 | # @array is changed 28 | my ($array_ref, @keep_only) = @_; 29 | if(not @$array_ref) { 30 | # Empty array: No need to look more at that 31 | return 1; 32 | } 33 | # A bit of shuffling of @ARGV needed as GetOptionsFromArray is not 34 | # supported everywhere 35 | my @save_argv; 36 | my $this_is_ARGV = (\@::ARGV == $array_ref); 37 | if(not $this_is_ARGV) { 38 | @save_argv = @::ARGV; 39 | @::ARGV = @{$array_ref}; 40 | } 41 | # If @keep_only set: Ignore all values except @keep_only 42 | my %options = options_hash(); 43 | if(@keep_only) { 44 | my (%keep,@dummy); 45 | @keep{@keep_only} = @keep_only; 46 | for my $k (grep { not $keep{$_} } keys %options) { 47 | # Store the value of the option in @dummy 48 | $options{$k} = \@dummy; 49 | } 50 | } 51 | my $retval = GetOptions(%options); 52 | if(not $this_is_ARGV) { 53 | @{$array_ref} = @::ARGV; 54 | @::ARGV = @save_argv; 55 | } 56 | return $retval; 57 | } 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /rand/rand: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | : <<=cut 4 | =pod 5 | 6 | =head1 NAME 7 | 8 | rand - Generate (pseudo-)random data 9 | 10 | 11 | =head1 SYNOPSIS 12 | 13 | rand 14 | 15 | 16 | =head1 DESCRIPTION 17 | 18 | B uses B to generate pseudorandom data. Just like B it generates an infinite amount of data, but it is much 20 | faster (400 MB/s on hardware from 2013). 21 | 22 | The quality is lower as there are only 2^256 different tables (this is 23 | still around the number of atoms in the visible universe). 24 | 25 | 26 | =head1 EXAMPLE 27 | 28 | Overwrite a harddisk with random data: 29 | 30 | rand >/dev/sda 31 | 32 | 33 | =head1 AUTHOR 34 | 35 | Copyright (C) 2016 Ole Tange, 36 | http://ole.tange.dk and Free Software Foundation, Inc. 37 | 38 | 39 | =head1 LICENSE 40 | 41 | Copyright (C) 2012 Free Software Foundation, Inc. 42 | 43 | This program is free software; you can redistribute it and/or modify 44 | it under the terms of the GNU General Public License as published by 45 | the Free Software Foundation; either version 3 of the License, or 46 | at your option any later version. 47 | 48 | This program is distributed in the hope that it will be useful, 49 | but WITHOUT ANY WARRANTY; without even the implied warranty of 50 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 51 | GNU General Public License for more details. 52 | 53 | You should have received a copy of the GNU General Public License 54 | along with this program. If not, see . 55 | 56 | 57 | =head1 DEPENDENCIES 58 | 59 | B uses B. 60 | 61 | 62 | =head1 SEE ALSO 63 | 64 | B 65 | 66 | 67 | =cut 68 | 69 | # Generate random 8-bit data by AES encrypting /dev/zero with a random 70 | # key 71 | key=$(openssl rand -hex 16) 72 | iv=$(openssl rand -hex 16) 73 | < /dev/zero openssl enc -aes-128-ctr -K $key -iv $iv 2>/dev/null 74 | -------------------------------------------------------------------------------- /transpose/transposewrap.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | 4 | use File::Temp qw(tempfile tempdir); 5 | 6 | #$Global::debug = 1; 7 | my $block = "30m"; 8 | debug("parallel --pipe --block $block -k --files -j150% transpose-par.pl\n"); 9 | my @files = `parallel --pipe --block $block -k --files -j150% transpose-par.pl`; 10 | chomp(@files); 11 | my $tmp = File::Temp::tempdir(CLEANUP => 0); 12 | my $fifo = "$tmp/0000000"; 13 | my $cmd = "mkfifo $fifo; paste > $fifo "; 14 | my (@fifos, @args); 15 | my $args_len = 0; 16 | my $max_line_length_allowed = `parallel --max-line-length-allowed`; 17 | 18 | while(@files) { 19 | push @args, shift @files; 20 | $args_len += length $args[$#args] + 1; 21 | if(length $cmd + $args_len > $max_line_length_allowed) { 22 | unshift @files, pop @args; 23 | push @fifos, $fifo; 24 | if(fork()) { 25 | } else { 26 | debug("($cmd @args &)\n"); 27 | `($cmd @args &)`; 28 | exit($?); 29 | } 30 | $fifo++; 31 | $cmd = "mkfifo $fifo; paste > $fifo "; 32 | @args = (); 33 | $args_len = 0; 34 | } 35 | } 36 | 37 | if(@args) { 38 | push @fifos, $fifo; 39 | if(fork()) { 40 | } else { 41 | debug("($cmd @args &)\n"); 42 | `($cmd @args &)`; 43 | exit($?); 44 | } 45 | } 46 | 47 | # make sure all fifos are created by the spawned shells 48 | my @non_existing_fifos = @fifos; 49 | while(@non_existing_fifos) { 50 | if(not -e $non_existing_fifos[0]) { 51 | usleep(1); 52 | } else { 53 | shift @non_existing_fifos; 54 | } 55 | } 56 | 57 | debug("paste @fifos\n"); 58 | system("paste @fifos"); 59 | 60 | unlink(@fifos); 61 | rmdir($tmp); 62 | 63 | sub usleep { 64 | # Sleep this many milliseconds. 65 | my $secs = shift; 66 | ::debug(int($secs),"ms "); 67 | select(undef, undef, undef, $secs/1000); 68 | } 69 | 70 | sub debug { 71 | # Returns: N/A 72 | $Global::debug or return; 73 | @_ = grep { defined $_ ? $_ : "" } @_; 74 | if($Global::fd{1}) { 75 | # Original stdout was saved 76 | my $stdout = $Global::fd{1}; 77 | print $stdout @_; 78 | } else { 79 | print @_; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /zram-init/zram: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ### BEGIN INIT INFO 3 | # Provides: zram 4 | # Required-Start: 5 | # Required-Stop: 6 | # Default-Start: 2 3 4 5 7 | # Default-Stop: 0 1 6 8 | # Short-Description: Increased Performance In Linux With zRam (Virtual Swap Compressed in RAM) 9 | # Description: Adapted from systemd scripts at https://github.com/mystilleef/FedoraZram 10 | ### END INIT INFO 11 | # Author: tradetaxfree http://crunchbanglinux.org/forums/topic/15344/zram-a-good-idea/ 12 | 13 | start() { 14 | # get the number of CPUs 15 | num_cpus=$(grep -c processor /proc/cpuinfo) 16 | # if something goes wrong, assume we have 1 17 | [ "$num_cpus" != 0 ] || num_cpus=1 18 | 19 | # set decremented number of CPUs 20 | decr_num_cpus=$((num_cpus - 1)) 21 | 22 | # get the amount of memory in the machine 23 | mem_total_kb=$(grep MemTotal /proc/meminfo | grep -E --only-matching '[[:digit:]]+') 24 | mem_total=$((mem_total_kb * 1024)) 25 | 26 | # load dependency modules 27 | modprobe zram zram_num_devices=$num_cpus || modprobe zram num_devices=$num_cpus || exit 1 28 | 29 | # initialize the devices 30 | for i in $(seq 0 $decr_num_cpus); do 31 | echo $((mem_total / num_cpus)) > /sys/block/zram$i/disksize 32 | done 33 | 34 | # Creating swap filesystems 35 | for i in $(seq 0 $decr_num_cpus); do 36 | mkswap /dev/zram$i 37 | done 38 | 39 | # Switch the swaps on 40 | for i in $(seq 0 $decr_num_cpus); do 41 | swapon -p 100 /dev/zram$i 42 | done 43 | } 44 | 45 | stop() { 46 | # get the number of CPUs 47 | num_cpus=$(grep -c processor /proc/cpuinfo) 48 | 49 | # set decremented number of CPUs 50 | decr_num_cpus=$((num_cpus - 1)) 51 | 52 | # Switching off swap 53 | for i in $(seq 0 $decr_num_cpus); do 54 | if [ "$(grep /dev/zram$i /proc/swaps)" != "" ]; then 55 | swapoff /dev/zram$i 56 | sleep 0.1 57 | fi 58 | done 59 | 60 | sleep 0.1 61 | modprobe -r zram 62 | } 63 | 64 | case "$1" in 65 | start) 66 | start 67 | ;; 68 | stop) 69 | stop 70 | ;; 71 | restart) 72 | stop 73 | sleep 3 74 | start 75 | ;; 76 | *) 77 | echo "Usage: $0 {start|stop|restart}" 78 | RETVAL=1 79 | esac 80 | exit $RETVAL 81 | -------------------------------------------------------------------------------- /transpose/transpose: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | use English; 4 | use FileCache; 5 | use File::Temp; 6 | 7 | my $delimiter = shift; 8 | my $buffer = shift; 9 | 10 | # Use at most 1000M before flushing 11 | $buffer ||= 1000_000_000; 12 | # Perl makes the buffer baloon to 10 times the requested value 13 | $buffer /= 10; 14 | $max_col_size = $buffer; 15 | my $delimiter_regexp = $delimiter; 16 | $delimiter_regexp =~ s/(\W)/\\$1/g; 17 | my @current; 18 | my $last_t = 0; 19 | my $lineno = 0; 20 | my %col; 21 | while(<>) { 22 | chomp; 23 | # Split current line into columns 24 | @current = split /$delimiter_regexp/o, $_; 25 | my $t = 0; 26 | map { 27 | push(@{$col{$t}},$_); 28 | $col_size{$t} += length $_; 29 | if($col_size{$t} > $max_col_size) { 30 | flush(\%col,$t); 31 | $col_size{$t} = 0; 32 | } 33 | $t++; 34 | } @current; 35 | if($t != $last_t) { 36 | if(0 == $last_t) { 37 | $last_t = $t; 38 | $max_col_size = $buffer/$last_t; 39 | } else { 40 | warning("Number of columns in line $NR: $t != $last_t\n"); 41 | } 42 | } 43 | } 44 | flush(\%col); 45 | merge(); 46 | 47 | sub flush { 48 | my $col_ref = shift; 49 | my @cols_to_flush = @_; 50 | if(not @cols_to_flush) { 51 | @cols_to_flush = keys %$col_ref; 52 | } 53 | for my $c (@cols_to_flush) { 54 | $Global::tempfile{$c} ||= tmpnam(); 55 | my $fh = cacheout $Global::tempfile{$c}; 56 | # This will print one delimiter too much, which we will deal with later 57 | print $fh map { $_,$delimiter } @{$col_ref->{$c}}; 58 | delete $col_ref->{$c}; 59 | } 60 | } 61 | 62 | sub merge { 63 | for my $c (sort keys %Global::tempfile) { 64 | my $fh = cacheout $Global::tempfile{$c}; 65 | # truncate by length of delimiter to get rid of the last $delimiter 66 | seek $fh,-length($delimiter),SEEK_END; 67 | truncate $fh, tell $fh; 68 | # Make sure the file is closed of writing 69 | close $fh; 70 | open($fh, "<", $Global::tempfile{$c}) || die; 71 | my $buf; 72 | while(sysread($fh,$buf,1000_000)) { 73 | print $buf; 74 | } 75 | print "\n"; 76 | unlink $Global::tempfile{$c}; 77 | } 78 | } 79 | 80 | sub warning { 81 | my @w = @_; 82 | print STDERR "transpose: Warning: ", @w; 83 | } 84 | 85 | sub error { 86 | my @w = @_; 87 | print STDERR "transpose: Error: ", @w; 88 | } 89 | -------------------------------------------------------------------------------- /tracefile/tracefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use Getopt::Long; 4 | 5 | $Global::progname = "tracefile"; 6 | 7 | Getopt::Long::Configure("bundling","pass_through"); 8 | get_options_from_array(\@ARGV) || die_usage(); 9 | 10 | if(not ($opt::exists or $opt::nonexists or $opt::all)) { 11 | $opt::all = 1; 12 | } 13 | 14 | my @cmd = shell_quote(@ARGV); 15 | my $dir = "."; 16 | my $pid = $opt::pid ? "-p $opt::pid" : ""; 17 | 18 | open(IN, "-|", "strace -ff $pid -e trace=file @cmd 2>&1") || die; 19 | while() { 20 | if(/chdir."(([^\\"]|\\[\\"nt])*)".\s*=\s*0/) { 21 | $dir = $1; 22 | } 23 | 24 | # [pid 30817] stat("transpose/100000files.tar.gz", {st_mode=S_IFREG|0644, st_size=140853248, ...}) = 0 25 | if(s/^[^\"]+"(([^\\"]|\\[\\"nt])*)".*/$1/) { 26 | # Matches the strace structure for a file 27 | my $file = shell_unquote($1); 28 | # Relative to $dir 29 | $file =~ s:^([^/]):$dir/$1:; 30 | my $print = 0; 31 | if($opt::all 32 | or 33 | ($opt::exists and -e $file) 34 | or 35 | ($opt::nonexists and not -e $file)) { 36 | $print = 1; 37 | } 38 | if($opt::unique and $seen{$file}++) { 39 | $print = 0; 40 | } 41 | $print and print $file,"\n"; 42 | } 43 | } 44 | 45 | sub options_hash { 46 | # Returns a hash of the GetOptions config 47 | return 48 | ("debug|D" => \$opt::debug, 49 | "uniq|unique|u" => \$opt::unique, 50 | "exists|exist|e" => \$opt::exists, 51 | "nonexists|nonexist|non-exists|non-exist|n" => \$opt::nonexists, 52 | "all|a" => \$opt::all, 53 | "pid|p=i" => \$opt::pid, 54 | ); 55 | } 56 | 57 | sub get_options_from_array { 58 | # Run GetOptions on @array 59 | # Returns: 60 | # true if parsing worked 61 | # false if parsing failed 62 | # @array is changed 63 | my $array_ref = shift; 64 | # A bit of shuffling of @ARGV needed as GetOptionsFromArray is not 65 | # supported everywhere 66 | my @save_argv; 67 | my $this_is_ARGV = (\@::ARGV == $array_ref); 68 | if(not $this_is_ARGV) { 69 | @save_argv = @::ARGV; 70 | @::ARGV = @{$array_ref}; 71 | } 72 | my @retval = GetOptions(options_hash()); 73 | if(not $this_is_ARGV) { 74 | @{$array_ref} = @::ARGV; 75 | @::ARGV = @save_argv; 76 | } 77 | return @retval; 78 | } 79 | 80 | sub shell_unquote { 81 | # Unquote strings from shell_quote 82 | # Returns: 83 | # string with shell quoting removed 84 | my @strings = (@_); 85 | my $arg; 86 | for my $arg (@strings) { 87 | if(not defined $arg) { 88 | $arg = ""; 89 | } 90 | $arg =~ s/'\n'/\n/g; # filenames with '\n' is quoted using \' 91 | $arg =~ s/\\([\002-\011\013-\032])/$1/g; 92 | $arg =~ s/\\([\#\?\`\(\)\{\}\*\>\<\~\|\; \"\!\$\&\'])/$1/g; 93 | $arg =~ s/\\\\/\\/g; 94 | } 95 | return wantarray ? @strings : "@strings"; 96 | } 97 | 98 | sub shell_quote { 99 | my @strings = (@_); 100 | for my $a (@strings) { 101 | $a =~ s/([\002-\011\013-\032\\\#\?\`\(\)\{\}\[\]\*\>\<\~\|\; \"\!\$\&\'\202-\377])/\\$1/g; 102 | $a =~ s/[\n]/'\n'/g; # filenames with '\n' is quoted using \' 103 | } 104 | return wantarray ? @strings : "@strings"; 105 | } 106 | 107 | sub die_usage { 108 | # Returns: N/A 109 | usage(); 110 | wait_and_exit(255); 111 | } 112 | 113 | sub usage { 114 | # Returns: N/A 115 | print join 116 | ("\n", 117 | "Usage:", 118 | "$Global::progname [-u] [-a] [-n] [-e] command [arguments]", 119 | "", 120 | "See 'man $Global::progname' for details", 121 | ""); 122 | } 123 | 124 | sub warning { 125 | my @w = @_; 126 | my $fh = $Global::original_stderr || *STDERR; 127 | my $prog = $Global::progname || "tracefile"; 128 | print $fh $prog, ": Warning: ", @w; 129 | } 130 | 131 | 132 | sub error { 133 | my @w = @_; 134 | my $fh = $Global::original_stderr || *STDERR; 135 | my $prog = $Global::progname || "tracefile"; 136 | print $fh $prog, ": Error: ", @w; 137 | } 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /transpose/transpose.pod: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | =head1 NAME 4 | 5 | transpose - transpose CSV file 6 | 7 | =head1 SYNOPSIS 8 | 9 | B [-d I] [I] 10 | 11 | =head1 DESCRIPTION 12 | 13 | B will read a CSV fie 14 | 15 | =head1 OPTIONS 16 | 17 | =over 9 18 | 19 | =item I 20 | 21 | Input CSV file. If none is given reads from STDIN (standard input). 22 | 23 | 24 | =item B<-d> I - not implemented 25 | 26 | Use I as delimiter in input and output. 27 | 28 | 29 | =back 30 | 31 | 32 | =head1 EXAMPLES 33 | 34 | =head2 EXAMPLE: Transpose a big CSV file 35 | 36 | cat medium.csv | transpose > muidem.csv 37 | 38 | =head1 DESIGN 39 | 40 | B is designed to deal efficiently with medium sized data 41 | (up to 30 TB per file) on systems with 250 MB RAM per CPU core. It 42 | works by chopping the input into 30 MB blocks. Each block is 43 | transposed in parallel and saved to disk. Then these files are pasted 44 | together and finally removed. 45 | 46 | =head1 REPORTING BUGS 47 | 48 | Report bugs to . 49 | 50 | 51 | =head1 AUTHOR 52 | 53 | Copyright (C) 2013 Ole Tange, http://ole.tange.dk and Free 54 | Software Foundation, Inc. 55 | 56 | 57 | =head1 LICENSE 58 | 59 | Copyright (C) 2013 Free Software Foundation, Inc. 60 | 61 | This program is free software; you can redistribute it and/or modify 62 | it under the terms of the GNU General Public License as published by 63 | the Free Software Foundation; either version 3 of the License, or 64 | at your option any later version. 65 | 66 | This program is distributed in the hope that it will be useful, 67 | but WITHOUT ANY WARRANTY; without even the implied warranty of 68 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 69 | GNU General Public License for more details. 70 | 71 | You should have received a copy of the GNU General Public License 72 | along with this program. If not, see . 73 | 74 | =head2 Documentation license I 75 | 76 | Permission is granted to copy, distribute and/or modify this documentation 77 | under the terms of the GNU Free Documentation License, Version 1.3 or 78 | any later version published by the Free Software Foundation; with no 79 | Invariant Sections, with no Front-Cover Texts, and with no Back-Cover 80 | Texts. A copy of the license is included in the file fdl.txt. 81 | 82 | =head2 Documentation license II 83 | 84 | You are free: 85 | 86 | =over 9 87 | 88 | =item B 89 | 90 | to copy, distribute and transmit the work 91 | 92 | =item B 93 | 94 | to adapt the work 95 | 96 | =back 97 | 98 | Under the following conditions: 99 | 100 | =over 9 101 | 102 | =item B 103 | 104 | You must attribute the work in the manner specified by the author or 105 | licensor (but not in any way that suggests that they endorse you or 106 | your use of the work). 107 | 108 | =item B 109 | 110 | If you alter, transform, or build upon this work, you may distribute 111 | the resulting work only under the same, similar or a compatible 112 | license. 113 | 114 | =back 115 | 116 | With the understanding that: 117 | 118 | =over 9 119 | 120 | =item B 121 | 122 | Any of the above conditions can be waived if you get permission from 123 | the copyright holder. 124 | 125 | =item B 126 | 127 | Where the work or any of its elements is in the public domain under 128 | applicable law, that status is in no way affected by the license. 129 | 130 | =item B 131 | 132 | In no way are any of the following rights affected by the license: 133 | 134 | =over 2 135 | 136 | =item * 137 | 138 | Your fair dealing or fair use rights, or other applicable 139 | copyright exceptions and limitations; 140 | 141 | =item * 142 | 143 | The author's moral rights; 144 | 145 | =item * 146 | 147 | Rights other persons may have either in the work itself or in 148 | how the work is used, such as publicity or privacy rights. 149 | 150 | =back 151 | 152 | =back 153 | 154 | =over 9 155 | 156 | =item B 157 | 158 | For any reuse or distribution, you must make clear to others the 159 | license terms of this work. 160 | 161 | =back 162 | 163 | A copy of the full license is included in the file as cc-by-sa.txt. 164 | 165 | =head1 DEPENDENCIES 166 | 167 | B uses Perl, B, B and B. 168 | 169 | 170 | =head1 SEE ALSO 171 | 172 | B(1), B(1), B(1) 173 | 174 | =cut 175 | 176 | -------------------------------------------------------------------------------- /reniced/reniced: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | init_whitelist(); 4 | renice_all(5*60); 5 | 6 | sub init_whitelist { 7 | my @whitelist_commands; 8 | my @whitelist_users = ("root", "syslog", "ntp", "bind", "snmp", "postfix"); 9 | if(-f "/etc/reniced/whitelist.users") { 10 | @whitelist_users = `cat /etc/reniced/whitelist.users`; 11 | chomp(@whitelist_users); 12 | } 13 | for (@whitelist_users) { 14 | $Global::whitelist_users{$_} = 1; 15 | } 16 | 17 | if(-f "/etc/reniced/whitelist.commands") { 18 | @whitelist_commands = `cat /etc/reniced/whitelist.commands`; 19 | chomp(@whitelist_commands); 20 | } 21 | for (@whitelist_commands) { 22 | $Global::whitelist_commands{$_} = 1; 23 | } 24 | } 25 | 26 | sub renice_all { 27 | my $cpu_seconds = shift; 28 | my $ps = ps(); 29 | my @pids_to_renice = grep_ps($cpu_seconds,$ps); 30 | my $user_pid_list = user_pid_list($ps,@pids_to_renice); 31 | my ($login,$pass,$uid,$gid); 32 | for my $user (keys %$user_pid_list) { 33 | if($user =~ /^\d+$/) { 34 | # All digits username => probably a >8 char username => lookup uid 35 | ($login,$pass,$uid,$gid) = getpwuid($user); 36 | } else { 37 | $login = $user; 38 | } 39 | renice_user($cpu_seconds, $login, $ps, @{$user_pid_list->{$user}}); 40 | } 41 | } 42 | 43 | sub renice_user { 44 | my ($cpu_seconds, $user, $ps, @pid) = (@_); 45 | my @command; 46 | for my $pid (@pid) { 47 | # Convert pid to human readable: 48 | # my_command (1192) 49 | push @command, $ps->{$pid}{'cmd'}."(".$pid.")"; 50 | } 51 | mail($cpu_seconds, $user, @command); 52 | renice(@pid); 53 | } 54 | 55 | sub mail { 56 | my($cpu_seconds, $user, @command) = @_; 57 | my @mail = 58 | ( 59 | 'From: The renice program ', 60 | "To: <$user>", 61 | 'Subject: Your program has been reniced', 62 | '', 63 | "Hi $user.", 64 | '', 65 | 'Your program:', 66 | '', 67 | " @command", 68 | '', 69 | "has been using more than $cpu_seconds CPU seconds. I have therefore niced it to nice level 15.", 70 | '', 71 | 'There is no harm done, this is purely for your information so you know what happened and how', 72 | 'to avoid it.', 73 | '', 74 | 'If you want to avoid it in the future, you can start the program with a different nice level:', 75 | '', 76 | ' nice -n XX your_command', 77 | '', 78 | 'where XX is:', 79 | ' 1 - urgent', 80 | ' 10 - normal', 81 | ' 15 - low', 82 | ' 18 - only use spare capacity', 83 | '', 84 | 'Regards', 85 | '', 86 | "The renice program", 87 | ); 88 | 89 | open(S,"|/usr/sbin/sendmail -t") or die; 90 | print S map { $_,"\n" } @mail; 91 | close S; 92 | open(LOG,">>/tmp/reniced") || die; 93 | print LOG map { $_,"\n" } @mail; 94 | close LOG; 95 | } 96 | 97 | sub user_pid_list { 98 | # given $ps and @pid return {user => @pids} 99 | my ($ps,@pid) = @_; 100 | my $user; 101 | for my $pid (@pid) { 102 | push @{$user->{$ps->{$pid}{'user'}}}, $pid; 103 | } 104 | return $user; 105 | } 106 | 107 | sub renice { 108 | my @pid = @_; 109 | `renice -n 15 -p @pid 2>&1`; 110 | return $?; 111 | } 112 | 113 | sub ps { 114 | # return: {pid}->{'nice' => nicelevel, 'user' => username, 'cmd' => command, 'cputime' => cpu_seconds_used} 115 | my @out = `ps -eo '%p %u %n %x %c'`; 116 | my $ps; 117 | shift @out; # Remove header 118 | for (@out) { 119 | if(/^\s*(\d+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+.*)$/) { 120 | # pid user nice cputime command 121 | my($pid, $user, $nice, $cputime, $cmd) = ($1, $2, $3, $4, $5); 122 | $ps->{$pid}{'user'} = $user; 123 | $ps->{$pid}{'cmd'} = $cmd; 124 | $ps->{$pid}{'nice'} = ($nice eq "-") ? 0 : $nice; 125 | if($cputime=~/((\d+)-)?(\d\d):(\d\d):(\d\d)/) { 126 | my $days = $2 ? $2 : 0; 127 | $ps->{$pid}{'cputime'} = $days*24*60*60+$3*60*60+$4*60+$5; 128 | } else { 129 | warn("cputime not matched: $cputime"); 130 | } 131 | } else { 132 | warn("ps line not matched: $_"); 133 | } 134 | } 135 | return $ps; 136 | } 137 | 138 | sub grep_ps { 139 | my ($maxcputime,$ps) = (@_); 140 | my @result; 141 | 142 | for my $pid (keys %$ps) { 143 | if($Global::whitelist_users{$ps->{$pid}{'user'}}) { 144 | # User is on the whitelist 145 | next; 146 | } 147 | if($Global::whitelist_commands{$ps->{$pid}{'cmd'}}) { 148 | # Command is on the whitelist 149 | next; 150 | } 151 | if($ps->{$pid}{'nice'} >= 1) { 152 | # Command is already niced 153 | next; 154 | } 155 | if($ps->{$pid}{'cputime'} > $maxcputime) { 156 | push @result, $pid; 157 | } 158 | } 159 | return @result; 160 | } 161 | -------------------------------------------------------------------------------- /tracefile/tracefile.pod: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | =head1 NAME 4 | 5 | tracefile - list files being accessed 6 | 7 | =head1 SYNOPSIS 8 | 9 | B [-aenu] I 10 | 11 | B [-aenu] -p I 12 | 13 | =head1 DESCRIPTION 14 | 15 | B will print the files being accessed by the command. 16 | 17 | =head1 OPTIONS 18 | 19 | =over 9 20 | 21 | =item I 22 | 23 | Command to run. 24 | 25 | 26 | =item B<-a> 27 | 28 | List all files. 29 | 30 | 31 | =item B<-e> 32 | 33 | List only existing files. 34 | 35 | 36 | =item B<-n> 37 | 38 | List only non-existing files. 39 | 40 | =item B<-p> I 41 | 42 | Trace process id. 43 | 44 | 45 | =item B<-u> 46 | 47 | List only files once. 48 | 49 | =back 50 | 51 | 52 | =head1 EXAMPLES 53 | 54 | =head2 EXAMPLE: Find the missing package 55 | 56 | Assume you have a program B. When it runs it fails with: I. It does not say with file is missing, but you 58 | have a hunch that you just need to install a package - you just do not 59 | know which one. 60 | 61 | tracefile -n -u foo | apt-file -f search - 62 | 63 | Here B tries to find B. If it fails, 64 | B will search for which package it is in: 65 | 66 | tracefile -n -u ls /usr/include/shisa.h | apt-file -f search - 67 | 68 | =head1 REPORTING BUGS 69 | 70 | Report bugs to . 71 | 72 | 73 | =head1 AUTHOR 74 | 75 | Copyright (C) 2012 Ole Tange, http://ole.tange.dk and Free 76 | Software Foundation, Inc. 77 | 78 | 79 | =head1 LICENSE 80 | 81 | Copyright (C) 2012 Free Software Foundation, Inc. 82 | 83 | This program is free software; you can redistribute it and/or modify 84 | it under the terms of the GNU General Public License as published by 85 | the Free Software Foundation; either version 3 of the License, or 86 | at your option any later version. 87 | 88 | This program is distributed in the hope that it will be useful, 89 | but WITHOUT ANY WARRANTY; without even the implied warranty of 90 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 91 | GNU General Public License for more details. 92 | 93 | You should have received a copy of the GNU General Public License 94 | along with this program. If not, see . 95 | 96 | =head2 Documentation license I 97 | 98 | Permission is granted to copy, distribute and/or modify this documentation 99 | under the terms of the GNU Free Documentation License, Version 1.3 or 100 | any later version published by the Free Software Foundation; with no 101 | Invariant Sections, with no Front-Cover Texts, and with no Back-Cover 102 | Texts. A copy of the license is included in the file fdl.txt. 103 | 104 | =head2 Documentation license II 105 | 106 | You are free: 107 | 108 | =over 9 109 | 110 | =item B 111 | 112 | to copy, distribute and transmit the work 113 | 114 | =item B 115 | 116 | to adapt the work 117 | 118 | =back 119 | 120 | Under the following conditions: 121 | 122 | =over 9 123 | 124 | =item B 125 | 126 | You must attribute the work in the manner specified by the author or 127 | licensor (but not in any way that suggests that they endorse you or 128 | your use of the work). 129 | 130 | =item B 131 | 132 | If you alter, transform, or build upon this work, you may distribute 133 | the resulting work only under the same, similar or a compatible 134 | license. 135 | 136 | =back 137 | 138 | With the understanding that: 139 | 140 | =over 9 141 | 142 | =item B 143 | 144 | Any of the above conditions can be waived if you get permission from 145 | the copyright holder. 146 | 147 | =item B 148 | 149 | Where the work or any of its elements is in the public domain under 150 | applicable law, that status is in no way affected by the license. 151 | 152 | =item B 153 | 154 | In no way are any of the following rights affected by the license: 155 | 156 | =over 2 157 | 158 | =item * 159 | 160 | Your fair dealing or fair use rights, or other applicable 161 | copyright exceptions and limitations; 162 | 163 | =item * 164 | 165 | The author's moral rights; 166 | 167 | =item * 168 | 169 | Rights other persons may have either in the work itself or in 170 | how the work is used, such as publicity or privacy rights. 171 | 172 | =back 173 | 174 | =back 175 | 176 | =over 9 177 | 178 | =item B 179 | 180 | For any reuse or distribution, you must make clear to others the 181 | license terms of this work. 182 | 183 | =back 184 | 185 | A copy of the full license is included in the file as cc-by-sa.txt. 186 | 187 | =head1 DEPENDENCIES 188 | 189 | B uses Perl, and B. 190 | 191 | 192 | =head1 SEE ALSO 193 | 194 | B(1) 195 | 196 | =cut 197 | 198 | -------------------------------------------------------------------------------- /upsidedown/upsidedown: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | =head1 NAME 4 | 5 | upsidedown - flip input upside down. 6 | 7 | =head1 SYNOPSIS 8 | 9 | B inputtext 10 | 11 | B | B 12 | 13 | =head1 DESCRIPTION 14 | 15 | B flips input text upside down. 16 | 17 | 18 | =head1 EXAMPLE: Flip 'Ole Tange' upside down 19 | 20 | upsidedown "'Ole Tange'" 21 | 22 | 23 | =head1 BUGS 24 | 25 | Upsidedown is not completely reversible. 26 | 27 | 28 | =head1 REPORTING BUGS 29 | 30 | Report bugs to . 31 | 32 | 33 | =head1 AUTHOR 34 | 35 | Copyright (C) 2012 Ole Tange, http://ole.tange.dk and Free 36 | Software Foundation, Inc. 37 | 38 | 39 | =head1 LICENSE 40 | 41 | Copyright (C) 2012 Free Software Foundation, Inc. 42 | 43 | This program is free software; you can redistribute it and/or modify 44 | it under the terms of the GNU General Public License as published by 45 | the Free Software Foundation; either version 3 of the License, or 46 | at your option any later version. 47 | 48 | This program is distributed in the hope that it will be useful, 49 | but WITHOUT ANY WARRANTY; without even the implied warranty of 50 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 51 | GNU General Public License for more details. 52 | 53 | You should have received a copy of the GNU General Public License 54 | along with this program. If not, see . 55 | 56 | =head2 Documentation license I 57 | 58 | Permission is granted to copy, distribute and/or modify this documentation 59 | under the terms of the GNU Free Documentation License, Version 1.3 or 60 | any later version published by the Free Software Foundation; with no 61 | Invariant Sections, with no Front-Cover Texts, and with no Back-Cover 62 | Texts. A copy of the license is included in the file fdl.txt. 63 | 64 | =head2 Documentation license II 65 | 66 | You are free: 67 | 68 | =over 9 69 | 70 | =item B 71 | 72 | to copy, distribute and transmit the work 73 | 74 | =item B 75 | 76 | to adapt the work 77 | 78 | =back 79 | 80 | Under the following conditions: 81 | 82 | =over 9 83 | 84 | =item B 85 | 86 | You must attribute the work in the manner specified by the author or 87 | licensor (but not in any way that suggests that they endorse you or 88 | your use of the work). 89 | 90 | =item B 91 | 92 | If you alter, transform, or build upon this work, you may distribute 93 | the resulting work only under the same, similar or a compatible 94 | license. 95 | 96 | =back 97 | 98 | With the understanding that: 99 | 100 | =over 9 101 | 102 | =item B 103 | 104 | Any of the above conditions can be waived if you get permission from 105 | the copyright holder. 106 | 107 | =item B 108 | 109 | Where the work or any of its elements is in the public domain under 110 | applicable law, that status is in no way affected by the license. 111 | 112 | =item B 113 | 114 | In no way are any of the following rights affected by the license: 115 | 116 | =over 2 117 | 118 | =item * 119 | 120 | Your fair dealing or fair use rights, or other applicable 121 | copyright exceptions and limitations; 122 | 123 | =item * 124 | 125 | The author's moral rights; 126 | 127 | =item * 128 | 129 | Rights other persons may have either in the work itself or in 130 | how the work is used, such as publicity or privacy rights. 131 | 132 | =back 133 | 134 | =back 135 | 136 | =over 9 137 | 138 | =item B 139 | 140 | For any reuse or distribution, you must make clear to others the 141 | license terms of this work. 142 | 143 | =back 144 | 145 | A copy of the full license is included in the file as cc-by-sa.txt. 146 | 147 | =head1 DEPENDENCIES 148 | 149 | B uses Perl, and the Perl module utf8. 150 | 151 | 152 | =head1 SEE ALSO 153 | 154 | B(1) 155 | 156 | =cut 157 | 158 | 159 | use utf8; 160 | 161 | my $down = ' @{}'. 162 | q{ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.,';0123456789?!"&()[]/\_‾=-<>}; 163 | my @up = (" ",qw(@ } {), 164 | qw{∀ q Ɔ p Ǝ Ⅎ ⅁ H I ſ ʞ ⅂ W N O Ԁ Ό ᴚ S ⊥ ∩ Ʌ M X ⅄ Z ɐ q ɔ p ǝ ɟ 6 ɥ ı ſ ʞ l}, 165 | qw{ɯ u o d b ɹ s ʇ n ʌ ʍ x ʎ z ˙ ' , ؛ 0 Ɩ 2 Ɛ ᔭ 5 9 Ɫ 8 6 ¿ ¡ „ ⅋ ) ( ] [ / \ ‾ _ = - > <}); 166 | 167 | my %up; 168 | my @down = split//,$down; 169 | @up{@up} = @down; 170 | @up{@down} = @up; 171 | 172 | binmode STDOUT, ':utf8'; 173 | binmode STDIN, ':utf8'; 174 | if(@ARGV) { 175 | print upsidedown("@ARGV"),"\n"; 176 | } else { 177 | while(<>) { 178 | print upsidedown($_),"\n"; 179 | } 180 | } 181 | 182 | sub upsidedown { 183 | my $string = shift; 184 | my @r = (); 185 | for (reverse split//,$string) { 186 | # Return the letter upside down 187 | # - or itself if not upside down defined 188 | push @r, ($up{$_} or $_); 189 | } 190 | return @r; 191 | } 192 | -------------------------------------------------------------------------------- /blink/blink: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | =head1 NAME 4 | 5 | blink - blink disks in a disk enclosure 6 | 7 | 8 | =head1 SYNOPSIS 9 | 10 | B [-n|--on|-f|--off|-t|--toggle] [I|--all|-d|--all-detected|-s|--all-slots] 11 | 12 | B I I 13 | 14 | 15 | =head1 DESCRIPTION 16 | 17 | B blinks a device in a harddisk enclosure. 18 | 19 | If no I is given the blinking be will toggled. 20 | 21 | If no I is given all detected disks in enclosures will be 22 | used. 23 | 24 | If no I and no I is given all detected harddisks will 25 | be off and all empty slots or slots with non-detected harddisks in 26 | enclosures will blink. These slots should be safe to remove. 27 | 28 | 29 | =head1 OPTIONS 30 | 31 | =over 9 32 | 33 | =item I 34 | 35 | What action to do. One of B<-n>, B<--on>, B<-f>, B<--off>, B<-t>, 36 | B<--toggle>. Default is B<--toggle>. 37 | 38 | 39 | =item I 40 | 41 | What slots to perform the action on. One of B<-d>, B<--all>, 42 | B<--all-detected>, B<-s>, B<--all-slots>, I. Default is 43 | B<--all-detected>. 44 | 45 | 46 | =item I 47 | 48 | The disk device to blink. Either as I or as I. 49 | 50 | 51 | =item B<--all-detected> 52 | 53 | =item B<--all> 54 | 55 | =item B<-d> 56 | 57 | Select all the detected devices. 58 | 59 | 60 | =item B<--all-slots> 61 | 62 | =item B<-s> 63 | 64 | Select all slots in the enclosures. 65 | 66 | 67 | =item B<--on> 68 | 69 | =item B<-n> 70 | 71 | Turn the blink on. 72 | 73 | 74 | =item B<--off> 75 | 76 | =item B<-f> 77 | 78 | Turn the blink off. 79 | 80 | 81 | =item B<--toggle> 82 | 83 | =item B<-t> 84 | 85 | Toggle the blink. 86 | 87 | 88 | =back 89 | 90 | =head1 EXAMPLE: Blink harddisk /dev/sdf 91 | 92 | To blink /dev/sdf 93 | 94 | B 95 | 96 | 97 | =head1 EXAMPLE: Blink all undetected slots 98 | 99 | It will be safe to remove disk from all the blinking slots as the 100 | slots are either empty or not detected. 101 | 102 | B 103 | 104 | 105 | =head1 EXAMPLE: Turn off blinking of all slots 106 | 107 | Turn off the blinking. 108 | 109 | B 110 | 111 | 112 | =head1 EXIT STATUS 113 | 114 | Always returns true. 115 | 116 | 117 | =head1 REPORTING BUGS 118 | 119 | Contact Ole Tange . 120 | 121 | 122 | =head1 AUTHOR 123 | 124 | Copyright (C) 2012 Ole Tange . 125 | 126 | 127 | =head1 LICENSE 128 | 129 | Copyright (C) 2012 Free Software Foundation, Inc. 130 | 131 | This program is free software; you can redistribute it and/or modify 132 | it under the terms of the GNU General Public License as published by 133 | the Free Software Foundation; either version 3 of the License, or 134 | at your option any later version. 135 | 136 | This program is distributed in the hope that it will be useful, 137 | but WITHOUT ANY WARRANTY; without even the implied warranty of 138 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 139 | GNU General Public License for more details. 140 | 141 | You should have received a copy of the GNU General Public License 142 | along with this program. If not, see . 143 | 144 | 145 | =head1 DEPENDENCIES 146 | 147 | B uses Perl and GNU Parallel. 148 | 149 | 150 | =head1 SEE ALSO 151 | 152 | B(1), B(1). 153 | 154 | =cut 155 | 156 | use Getopt::Long; 157 | 158 | GetOptions( 159 | "n|on" => \$::opt_on, 160 | "f|off" => \$::opt_off, 161 | "t|toggle" => \$::opt_toggle, 162 | "d|all|all-detected|alldetected" => \$::opt_alldetected, 163 | "s|all-slots|allslots" => \$::opt_allslots, 164 | ); 165 | 166 | my @more_args = (); 167 | if(@ARGV) { 168 | for(@ARGV) { 169 | s{/dev/}{}g; 170 | if(/^md/) { 171 | # RAID device. Try to find the matching physical devices 172 | my $md = $_; 173 | for my $line (grep /^$md :/, `cat /proc/mdstat`) { 174 | # md1 : active raid6 sdat[14](S) sdx[13] sds[12](S) sdc[6](S) sdb[0] sdm[9] sdk[7] sdaa[10] sdi[5] sdh[4] 175 | while($line =~ s/(\S+)\[//) { 176 | push @more_args, $1; 177 | } 178 | } 179 | } 180 | } 181 | } 182 | push @ARGV,@more_args; 183 | 184 | 185 | if(not ($::opt_on or $::opt_off or $::opt_toggle or 186 | $::opt_alldetected or $::opt_allslots or @ARGV)) { 187 | # Default: 188 | # Turn on all 189 | # Turn off all-detected 190 | $locate = "/sys/class/enclosure/*/*/locate"; 191 | on($locate); 192 | $locate = "/sys/class/enclosure/*/*/device/enclosure*/locate"; 193 | off($locate); 194 | exit; 195 | } 196 | 197 | if($::opt_alldetected) { 198 | $locate = "/sys/class/enclosure/*/*/device/enclosure*/locate"; 199 | } elsif($::opt_allslots) { 200 | $locate = "/sys/class/enclosure/*/*/locate"; 201 | } else { 202 | if($#ARGV == 0) { 203 | $dev = shift; 204 | } else { 205 | local($"=","); 206 | $dev = @ARGV ? "{@ARGV}" : "*"; 207 | } 208 | $locate = "/sys/class/enclosure/*/*/device/block/$dev/../../enclosure*/locate"; 209 | } 210 | 211 | if($::opt_on) { 212 | on($locate); 213 | } elsif($::opt_off) { 214 | off($locate); 215 | } else { 216 | toggle($locate); 217 | } 218 | 219 | 220 | sub on { 221 | my $locate = shift; 222 | print(q{bash -c 'parallel -j1 echo 1 \\> {} ::: }. $locate."'\n"); 223 | system(q{bash -c 'parallel -j1 echo 1 \\> {} ::: }. $locate."'\n"); 224 | } 225 | 226 | 227 | sub off { 228 | my $locate = shift; 229 | print(q{bash -c 'parallel -j1 echo 0 \\> {} ::: }. $locate."'\n"); 230 | system(q{bash -c 'parallel -j1 echo 0 \\> {} ::: }. $locate."'\n"); 231 | } 232 | 233 | 234 | sub toggle { 235 | my $locate = shift; 236 | # If the file 'locate' contains 1 it should be put to 0. 237 | print(q{bash -c 'parallel -j1 grep -q 1 {} \; echo \$? \\> {} ::: }. $locate."'\n"); 238 | system(q{bash -c 'parallel -j1 grep -q 1 {} \; echo \$? \\> {} ::: }. $locate."'\n"); 239 | } 240 | -------------------------------------------------------------------------------- /timestamp/timestamp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | =head1 NAME 4 | 5 | timestamp - prepend timestamp to output 6 | 7 | =head1 SYNOPSIS 8 | 9 | B | B [--delta] [--rfc|--iso|--iso-time|--epoch] 10 | 11 | =head1 DESCRIPTION 12 | 13 | B prepends stdin (standard input) with a timestamp. 14 | 15 | =over 9 16 | 17 | =item B<--delta> (default) 18 | 19 | Regard start time as epoch and thus show difference between start time 20 | and now. 21 | 22 | If B<--delta> is repeated: The time spent between each line. 23 | 24 | 25 | =item B<--rfc> 26 | 27 | Output time format in RFC822 (E.g. Wed, 30 Jan 2013 13:57:58 GMT). 28 | 29 | 30 | =item B<--iso> 31 | 32 | Output time format in ISO8601 (E.g. 2013-01-30T13:57:58.322). 33 | 34 | 35 | =item B<--iso-time> 36 | 37 | Output time format in ISO8601/time only (E.g. 13:57:58.322). 38 | 39 | 40 | =item B<--epoch> (default) 41 | 42 | Output time format as seconds since 1970-01-01T00:00:00 (E.g. 1359557768.423). 43 | 44 | =back 45 | 46 | =head1 EXAMPLES 47 | 48 | =head2 Timestamp vmstat 49 | 50 | B 51 | 52 | 53 | =head2 Timestamp each step in setting up/tearing down ssh connection: 54 | 55 | B&1 | timestamp --delta --epoch> 56 | 57 | 58 | =head1 REPORTING BUGS 59 | 60 | B is part of tangetools. Report bugs to . 61 | 62 | 63 | =head1 AUTHOR 64 | 65 | Copyright (C) 2013 Ole Tange http://ole.tange.dk 66 | 67 | 68 | =head1 LICENSE 69 | 70 | Copyright (C) 2013 Free Software Foundation, Inc. 71 | 72 | This program is free software; you can redistribute it and/or modify 73 | it under the terms of the GNU General Public License as published by 74 | the Free Software Foundation; either version 3 of the License, or 75 | at your option any later version. 76 | 77 | This program is distributed in the hope that it will be useful, 78 | but WITHOUT ANY WARRANTY; without even the implied warranty of 79 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 80 | GNU General Public License for more details. 81 | 82 | You should have received a copy of the GNU General Public License 83 | along with this program. If not, see . 84 | 85 | =head2 Documentation license I 86 | 87 | Permission is granted to copy, distribute and/or modify this documentation 88 | under the terms of the GNU Free Documentation License, Version 1.3 or 89 | any later version published by the Free Software Foundation; with no 90 | Invariant Sections, with no Front-Cover Texts, and with no Back-Cover 91 | Texts. A copy of the license is included in the file fdl.txt. 92 | 93 | =head2 Documentation license II 94 | 95 | You are free: 96 | 97 | =over 9 98 | 99 | =item B 100 | 101 | to copy, distribute and transmit the work 102 | 103 | =item B 104 | 105 | to adapt the work 106 | 107 | =back 108 | 109 | Under the following conditions: 110 | 111 | =over 9 112 | 113 | =item B 114 | 115 | You must attribute the work in the manner specified by the author or 116 | licensor (but not in any way that suggests that they endorse you or 117 | your use of the work). 118 | 119 | =item B 120 | 121 | If you alter, transform, or build upon this work, you may distribute 122 | the resulting work only under the same, similar or a compatible 123 | license. 124 | 125 | =back 126 | 127 | With the understanding that: 128 | 129 | =over 9 130 | 131 | =item B 132 | 133 | Any of the above conditions can be waived if you get permission from 134 | the copyright holder. 135 | 136 | =item B 137 | 138 | Where the work or any of its elements is in the public domain under 139 | applicable law, that status is in no way affected by the license. 140 | 141 | =item B 142 | 143 | In no way are any of the following rights affected by the license: 144 | 145 | =over 9 146 | 147 | =item * 148 | 149 | Your fair dealing or fair use rights, or other applicable 150 | copyright exceptions and limitations; 151 | 152 | =item * 153 | 154 | The author's moral rights; 155 | 156 | =item * 157 | 158 | Rights other persons may have either in the work itself or in 159 | how the work is used, such as publicity or privacy rights. 160 | 161 | =back 162 | 163 | =item B 164 | 165 | For any reuse or distribution, you must make clear to others the 166 | license terms of this work. 167 | 168 | =back 169 | 170 | A copy of the full license is included in the file as cc-by-sa.txt. 171 | 172 | =head1 DEPENDENCIES 173 | 174 | B uses Perl and the Getopt::Long and Time::HiRes modules. 175 | 176 | 177 | =head1 SEE ALSO 178 | 179 | B