- od początku pliku (skad = 0) - od aktualne pozycji (1) - od końca pliku (2)
Gdy nie jest znane miejsce należy go ustalić tworząc indeksy (położenie miejsc charakterystycznych) na przykład w osobnym pliku. Czytanie od zadanej linii jest niemożliwe bez wczytania poprzednich linii.
io('file.txt') > $contents;
$content > io('file.txt');
$content >> io('file.txt');
io('copy.txt') < io('file.txt');
io('more.txt') >> io('all.txt');
print "$_\n" for io(".")->all(0)
(open FH,"<+plik") lub dopisywać na końcu (open FH,">>plik").W celu dodania lub skasowania czegoś ze środka lub początku pliku, należy przepisać cały plik.
Do dyspozycji jest także konstrukcja jednolinijkowa zamieniająca np. piątą linię:
perl -pli -e '$_="nowa piąta linia" if $.==5' plik
@pliki = `ls *.txt`;
@pliki = glob('*.txt');
Zamiast niej lepiej użyć:
opendir(KATALOG,".");
@pliki = grep { /\.txt$/ } readdir KATALOG;
closedir KATALOG;
By ustawić znalezione powyżej pliki z rozszerzeniem .txt (pomijając grep'a - wszystkie) w kolejności czasów modyfikacji:
@pliki = sort { (stat($b))[9] <=> (stat($a))[9] } @pliki;
Do szukania (/usr/home) również w podkatalogach (plików .pm) można użyć systemowego find lub lepiej modułu File::Find.
use File::Find; %found = ( ); find( \&wanted, '/usr/home' ); $wynik = join "\n", keys %found; print "$wynik\n";
sub wanted {
$found{( split "/", $File::Find::name )[4] } = 1 if /\.pm$/;
}
Uproszczona wersja tego modułu to File::List. Jest też polecenie systemowe find2perl, konwertujące systemowego find'a na skrypt perlowy.
use HTTPD::UserAdmin ();
HTTPD::UserAdmin
->new(DB => "/foo/.htpasswd")
->add($username => $password);
Do wczytania hasła z klawiatury dobrze jest użyć modułu Term::ReadKey lub Term::ReadLine, Term::ReadPassword.
use Term::ReadKey;
ReadMode('noecho');
$password = ReadLine(0);
ReadMode('restore');
Jeśli perl (i system haseł ukrytych) został poprawnie zainstalowany funkcje getpw*() [np. getpwnam()] dają dostęp do odczytania haseł użytkowników. (Przy systemie haseł ukrytych tylko, gdy są wywoływane przez administratora)
$pwd = (getpwuid($<))[1]; $salt = substr($pwd, 0, 2); # salt to pierwsze dwa znaki hasla
if (crypt($haslo, $salt) ne $pwd) { die "Sorry...\n"; } else { print "ok\n"; }
Zmiana hasła wiąże się ze stworzeniem nowego pliku w odpowiednim formacie, opisanym w manie do passwd i zainstalowaniem go za pomocą opisanej w UNIXowym manie funkcji pwd_mkdb. Hasło należy wcześniej zakodować, przy użyciu funkcji crypt za pomocą wygenerowanego wcześniej (patrz niżej) dwubajtowego salta.
Przydatny może okazać się moduł Authen-PAM.
W przypadku kodowania haseł MD5 zastosowanie znajduje odpowiedni moduł:
use MD5;
$md5=new MD5;
$md5->add("$haselko");
$digest= $md5->digest();
lub
use Crypt::PasswdMD5;
print unix_md5_crypt("alamakota", "QYeZBvQu")."\n";
W zakodowanym haśle salt jest miedzy drugim a trzecim znakiem $.
Do wygenerowania hasła może służyć poniższe.
@chars = ( "A" .. "Z", "a".."z", 0..9, qw(! @ $ % ^ & * ));
$string = join("",@chars[ map { rand @chars } ( 1 .. 64 ) ]);
$mode = sprintf "%04o", (stat $file)[2] & 0777;
jest jeszcze dodana stała 0100000 - oznaczająca zwykły plik.
Oprócz stat jest jeszcze funkcja -X (perldoc -f -X) z różnymi sprawdzaniami pliku.
Do tego mamy funkcję readlink lub moduł File::Spec::Link
my ($s, $min, $h, $d, $m, $y, $weekday);
if($filename and -e $filename) {
($s, $min, $h, $d, $m, $y, $weekday) =
localtime((stat(_))[9]); # juz raz bylo stat, wiec mozna uzyc _
$y += 1900;
$m ++; # zeby byl z przedzialu 1-12
}
lub
use POSIX; use File::stat;
print strftime "%d-%m-%Y", localtime( (stat($filename))->mtime );
$teraz=time; utime $teraz,$teraz,@lista_plikow;
$wielkosc=(stat("nazwa-pliku.txt"))[7];
$wielkosc= -s "nazwa-pliku.txt";
$wielkosc=(stat("nazwa-pliku.txt"))->size;
Do zmiany nazwy służy funkcja rename.
unlink($filename);
truncate F, 1000;
obcina plik otwarty jako F do 1000 bajtów. Tylko że ta funkcja nie musi działać - musisz przetestować czy w Twoim systemie operacyjnym jest zaimplementowana.
rand($.) < 1 && ($line = $_) while <>;
Funkcja ta nie działa na systemach firmy Microsoft. Zamiast niej stosujemy moduły LockFile::Simple lub File::Lock.
Flock ma dwa parametry: uchwyt pliku i rodzaj operacji.
use Fcntl ':flock';
sub lock { flock(MBOX,LOCK_EX); seek(MBOX, 0, 2); }
sub unlock { flock(MBOX,LOCK_UN); }
open(MBOX, ">>/usr/spool/mail/$ENV{'USER'}")
or die "Can't open mailbox: $!";
lock();
print MBOX $msg,"\n\n";
unlock();
By funkcja flock działała poprawnie plik musi być otwarty do pisania (lub dopisywania), czyli można ograniczać po otwarciu i przed zamknięciem pliku. Zamknięcie pliku znosi ograniczenie.
flock(LOCK_EX) blokuje wszystkie procesy próbujące zrobić flock na tym pliku. flock(LOCK_SH) blokuje procesy próbujące zrobić flock(LOCK_EX) (w domyśle: piszące do pliku), ale nie blokuje procesów wykonujących flock(LOCK_SH). W rezultacie wiele procesów czytających ma jednocześnie dostęp do pliku, ale proces piszący zostanie zablokowany do czasu, aż wszystki czytające zwolnią blokadę.
Flock czeka na odblokowanie, o ile nie dodasz LOCK_NB, wtedy wróci z błędem i możesz na to zareagować.
(LOCK_SH = 1, LOCK_EX = 2, LOCK_NB = 4, LOCK_UN = 8 - zazwyczaj).
use Cwd; $dir = cwd;
open( STDOUT, ">/dev/null" ); open( STDERR, ">/dev/null" );
lub:
close (STDOUT); close (STDERR);
Archive::Zip Archive::Tar Compress::Bzip2 Compress::Zlib (do gzipa) PerlIO::gzip
use Digest::MD5; $dx = new Digest::MD5; subdir($DIR); print "MD5($DIR) = ", $dx->hexdigest, "\n";
sub subdir {
my $dir = shift;
opendir(D, $dir);
my @list = grep { ! /^\.\.?$/ } readdir(D);
closedir(D);
for(@list) {
if (-d "$dir/$_") { subdir("$dir/$_"); }
elsif (-f _) {
open(F, "$dir/$_");
$dx->addfile(F);
close(F);
}
}
}