\cat programming cat: unix
Put the following script (cleantmp) in root's crontab:
#! /usr/bin/perl -w
# cleantmp: Remove old files from /tmp partition
# Copyright (C) 1997 by Guy Geens
# Snail Mail:
# Zwijnaardsesteenweg 183
# 9000 Gent
# Belgium
use File::Find;
# Security measure: chroot to /tmp
$tmpdir = '/tmp/';
chdir ($tmpdir) || die "$tmpdir not accessible: $!";
if (chroot($tmpdir)) { # chroot() fails when not run by root
($prefix = $tmpdir) =~ s,/+$,,;
$root = '/';
$test = 0;
} else {
# Not run by root - test only
$prefix = '';
$root = $tmpdir;
$test = 1;
}
@list = ();
&find(\&do_files, $root);
&find(\&do_dirs, $root);
if (@list) {
print "Cleaned $tmpdir\n";
print "Deleted files are:\n";
for (sort @list) {
print "$prefix$_\n";
}
}
exit;
sub do_files {
(($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) &&
(-f _ || -l _ ) &&
(int(-A _) > 3) &&
! /^\.X.*lock$/ &&
&removefile ($_) && push @list, $File::Find::name;
}
sub do_dirs {
/^\..*-unix$/ && ($File::Find::prune = 1) ||
(($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) &&
-d _ && ($nlink == 2) &&
! /^lost\+found$/ &&
&removedir ($_) && push @list, "$File::Find::name/";
}
sub removedir {
if ( $test ) {
1;
} else {
# Can't use @_: rmdir doesn't take a list argument
rmdir $_[0];
}
}
sub removefile {
if ( $test ) {
1;
} else {
unlink @_;
}
}
On some machines, the user is not allowed to execute /usr/bin/env or it's not available. Even worse is that options cannot be passed to an interpreter.
#!/usr/bin/env perl ...
http://lists.gnu.org/archive/html/bug-coreutils/2004-05/msg00173.html
By setting the PERL environment variable, one can override the default perl version.
#!/bin/sh
exec "${PERL:-perl}" -x -S "$0" ${1+"$@"}
#!perl -w
...
By the way, what does ${1+"$@"} mean?
For CGIs which are usually out of PATH, the following code (without -S) would be more portable:
#!/bin/sh exec perl -x "$0" "$@" #!perl ...
#!/bin/sh
# the next line restarts using tclsh \
exec "${TCLSH:-tclsh} "$0" "$@"
...
#!/bin/sh
# (C) 2006 GPL by Huidae Cho
awk '
BEGIN{
for(i = 0; i < 10; i++)
hex[i] = i
hex["A"] = hex["a"] = 10
hex["B"] = hex["b"] = 11
hex["C"] = hex["c"] = 12
hex["D"] = hex["d"] = 13
hex["E"] = hex["e"] = 14
hex["F"] = hex["f"] = 15
}
{
gsub(/\+/, " ")
i = $0
while(match(i, /%../)){
if(RSTART > 1)
printf "%s", substr(i, 1, RSTART-1)
printf "%c", hex[substr(i, RSTART+1, 1)] * 16 + hex[substr(i, RSTART+2, 1)]
i = substr(i, RSTART+RLENGTH)
}
print i
}
'
OK, OK, I said "One-liner" urldecode functions. Try this! :-)
$ alias urldecode="awk '"'BEGIN{for(i=0;i<10;i++)hex[i]=i;hex["A"]=hex["a"]=10;hex["B"]=hex["b"]=11;hex["C"]=hex["c"]=12;hex["D"]=hex["d"]=13;hex["E"]=hex["e"]=14;hex["F"]=hex["f"]=15;}{gsub(/\+/," ");i=$0;while(match(i,/%../)){;if(RSTART>1);printf"%s",substr(i,1,RSTART-1);printf"%c",hex[substr(i,RSTART+1,1)]*16+hex[substr(i,RSTART+2,1)];i=substr(i,RSTART+RLENGTH);}print i;}'"'"
$ echo "%31+%32%0A%33+%34" | urldecode
1 2
3 4
This script uses an extension of GNU sed (\xNN).
# (C) 2006 GPL by Huidae Cho
urldecode(){
echo "$@" | sed 's/^.*$/'"`echo "$@" | sed 'y/+/ /; s/%/\\\\x/g; s/\//\\\\\//g'`"'/'
}
$ urldecode "%31+%32%0A%33+%34"
1 2
3 4
It's extremely fast!
# (C) 2004 GPL by Huidae Cho
urldecode(){
echo -e "$(sed 'y/+/ /; s/%/\\x/g')"
}
$ echo "%31+%32%0A%33+%34" | urldecode
or
$ echo -e "$(echo "%31+%32%0A%33+%34" | sed 'y/+/ /; s/%/\\x/g')"
outputs
1 2 3 4
Pure bash version: http://thijs.dalhuijsen.com/code/index.shtml?req=5
Two good examples from the bash man page:
ls > dirlist 2>&1
ls 2>&1 > dirlist
Programmatically, it's left to right, but actual stream is right to left.