/l3/users/su/mrg/mrgar.mrg.com/su :1 :2 :3 :4 :5 :6 :7 :8 :9 :10 :11 :12 :13 :14 :15 :16 :17 :18 :19 :20 :21 :22 :23 :24 :25 :26 :27 :28 :29 :30 :31 :32 :33 :34 :35 :36 :37 :38 :39 :40 |
|
#l
total 703 drwxr-xr-x 16 root root 384 Sep 7 16:51 ../ drwxr-xr-x 4 su root 2696 Jul 18 16:07 ./ -rwxr-xr-x 1 root root 4701 Jul 18 16:07 AutoCreateWhite_List -rwxr-xr-x 1 root root 268 Jun 8 09:08 Check_Squiddaemon -rwxr-xr-x 1 root root 265 Jun 8 09:05 Check_Samsdaemon -rwx------ 1 root root 672 Jun 8 09:04 Spamheaders -rwxr-xr-x 1 su root 2248 Jun 8 09:04 ShutdownUrodov -rwxr-xr-x 1 root root 1840 Jun 8 09:04 NUlog -rwx------ 1 root root 1240 Jun 8 09:03 MaxSize ... -rwx------ 1 root root 71 Mar 4 2010 CGP_logs -rwx------ 1 root root 760 Mar 4 2010 Fired_Users -rwx------ 1 root root 795 Mar 4 2010 MailFromSiteMrgarant.ru -rw------- 1 root root 748 Mar 4 2010 ParseExcel -rwx------ 1 root root 159 Mar 4 2010 Sa-learn -rwxr-xr-x 1 root root 6188 Mar 4 2010 faxanswer -rwxr-xr-x 1 root root 6300 Mar 4 2010 faxconfig -rwxr-xr-x 1 root root 6144 Mar 4 2010 faxdeluser -rwx------ 1 root root 46247 Mar 6 2004 xcode -rw-rw-r-- 1 root root 222 Mar 6 2004 xcodeln.pl |
#ls
![]() AccessSpam.Reload Fired_Users Spamheaders ArchCGP_Logs Getstat.pl Sync_SA_DCC_Whitelist Auto-Sa-learn ImInspector VoipBalance AutoCreateWhite_List KillS99local aimSniff.Cyr-005.pl CGP MS_CGP_SYNC.sh backup.ais CGP_logs MailBoxFull backup.ais.16 CSF MailFromSiteMrgarant.ru backup.configs Calls MakeSpam backup.nas CheckRaids MaxSize backup.vm Check_Samsdaemon Mount_ORION_Base backup.wavs ... Create_SPAM_Folder.MRGARANT2.pl ReloadSquid fincheck Create_SPAM_Folder.MRGARANT3.pl RemakeMailbox get_temp_apc Create_SPAM_Folder.pl RemakeMailboxSPAM mysqltuner.pl DCC Restrict_SMTP nOname1 DCC_stat Rsync_Zmail restrictsmtp DaySpamers SPAMERS rota DayUP Sa-learn runflow DecodeMp3toWav ShutdownUrodov sPam Del_CGP_dat_files Sipnet_cash xcode Find_CGP_dat_files Spam_to_mrgarant xcodeln.pl |
#ls
AccessSpam.Reload Fired_Users Spamheaders ArchCGP_Logs Getstat.pl Sync_SA_DCC_Whitelist Auto-Sa-learn ImInspector VoipBalance AutoCreateWhite_List KillS99local aimSniff.Cyr-005.pl CGP MS_CGP_SYNC.sh backup.ais CGP_logs MailBoxFull backup.ais.16 CSF MailFromSiteMrgarant.ru backup.configs Calls MakeSpam backup.nas CheckRaids MaxSize backup.vm Check_Samsdaemon Mount_ORION_Base backup.wavs ... Create_SPAM_Folder.MRGARANT2.pl ReloadSquid fincheck Create_SPAM_Folder.MRGARANT3.pl RemakeMailbox get_temp_apc Create_SPAM_Folder.pl RemakeMailboxSPAM mysqltuner.pl DCC Restrict_SMTP nOname1 DCC_stat Rsync_Zmail restrictsmtp DaySpamers SPAMERS rota DayUP Sa-learn runflow DecodeMp3toWav ShutdownUrodov sPam Del_CGP_dat_files Sipnet_cash xcode Find_CGP_dat_files Spam_to_mrgarant xcodeln.pl |
#Find_CGP_dat_files
![]() umount: /mnt/dat: not mounted mount.cifs kernel mount options: unc=//10.10.101.1\e$,user=root,,,,,domain=MRG,ver=1,credentials=/root/mount_smb_cred,rw,file_mode=0664,dir_mode=0775,iocharset=utf8,ip=10.10.101.1,pass=******** 47312 /mnt/dat/PROFILES/aki_ey/Application Data/Microsoft/Outlook/Outlook/akimova@mrggroup.ru.dat 13156 /mnt/dat/PROFILES/bag_mb/Application Data/Microsoft/Outlook/Outlook/operator.dms@mrggroup.ru.dat 52968 /mnt/dat/PROFILES/ber_ig/Application Data/Microsoft/Outlook/Outlook/beresneva@mrggroup.ru.dat 16548 /mnt/dat/PROFILES/fed_om/Application Data/Microsoft/Outlook/Outlook/operator.dms@mrggroup.ru.dat 19872 /mnt/dat/PROFILES/fom_or/Application Data/Microsoft/Outlook/Outlook/fomina@mrggroup.ru.dat 1184404 /mnt/dat/PROFILES/gal_ed/Application Data/Microsoft/Outlook/Outlook/galicina@mrggroup.ru.dat 561128 /mnt/dat/PROFILES/ged_sv/Application Data/Microsoft/Outlook/Outlook/gede@mrggroup.ru.dat 46460 /mnt/dat/PROFILES/gor_ea/Application Data/Microsoft/Outlook/Outlook/e.a.gordeeva@mrggroup.ru.dat ... 972796 /mnt/dat/profiles$/pop_ev/Application Data/Microsoft/Outlook/Outlook/epopova@mrggroup.ru.dat 1335736 /mnt/dat/profiles$/sap_vn/Application Data/Microsoft/Outlook/Outlook/sapsai@mrggroup.ru.dat 400444 /mnt/dat/profiles$/sev_aa/Application Data/Microsoft/Outlook/Outlook/a.a.sevostianov@mrggroup.ru.dat 601140 /mnt/dat/profiles$/shk_ss.V2/AppData/Roaming/Microsoft/Outlook/Outlook/shkvarin@mrggroup.ru.dat 1383060 /mnt/dat/profiles$/svi_td/Application Data/Microsoft/Outlook/Outlook/t.d.sviridova@mrggroup.ru.dat 610748 /mnt/dat/profiles$/tep_la.V2/AppData/Roaming/Microsoft/Outlook/Outlook/teptsova@mrggroup.ru.dat 410844 /mnt/dat/profiles$/tru_ma/Application Data/Microsoft/Outlook/Outlook/ybitki@mrgarant.ru.dat 544272 /mnt/dat/profiles$/vor_ya/Application Data/Microsoft/Outlook/Outlook/y.a.vorontsova@mrggroup.ru.dat 1113804 /mnt/dat/profiles$/zlo_ov/Application Data/Microsoft/Outlook/Outlook/zlotya@mrggroup.ru.dat 21721472 |
#Find_CGP_dat_files
umount: /mnt/dat: not mounted mount.cifs kernel mount options: unc=//10.10.101.1\e$,user=root,,,,,domain=MRG,ver=1,credentials=/root/mount_smb_cred,rw,file_mode=0664,dir_mode=0775,iocharset=utf8,ip=10.10.101.1,pass=******** 47312 /mnt/dat/PROFILES/aki_ey/Application Data/Microsoft/Outlook/Outlook/akimova@mrggroup.ru.dat 13156 /mnt/dat/PROFILES/bag_mb/Application Data/Microsoft/Outlook/Outlook/operator.dms@mrggroup.ru.dat 52968 /mnt/dat/PROFILES/ber_ig/Application Data/Microsoft/Outlook/Outlook/beresneva@mrggroup.ru.dat 16548 /mnt/dat/PROFILES/fed_om/Application Data/Microsoft/Outlook/Outlook/operator.dms@mrggroup.ru.dat 19872 /mnt/dat/PROFILES/fom_or/Application Data/Microsoft/Outlook/Outlook/fomina@mrggroup.ru.dat 1184404 /mnt/dat/PROFILES/gal_ed/Application Data/Microsoft/Outlook/Outlook/galicina@mrggroup.ru.dat 561128 /mnt/dat/PROFILES/ged_sv/Application Data/Microsoft/Outlook/Outlook/gede@mrggroup.ru.dat 46460 /mnt/dat/PROFILES/gor_ea/Application Data/Microsoft/Outlook/Outlook/e.a.gordeeva@mrggroup.ru.dat ... 972796 /mnt/dat/profiles$/pop_ev/Application Data/Microsoft/Outlook/Outlook/epopova@mrggroup.ru.dat 1335736 /mnt/dat/profiles$/sap_vn/Application Data/Microsoft/Outlook/Outlook/sapsai@mrggroup.ru.dat 400444 /mnt/dat/profiles$/sev_aa/Application Data/Microsoft/Outlook/Outlook/a.a.sevostianov@mrggroup.ru.dat 601140 /mnt/dat/profiles$/shk_ss.V2/AppData/Roaming/Microsoft/Outlook/Outlook/shkvarin@mrggroup.ru.dat 1383060 /mnt/dat/profiles$/svi_td/Application Data/Microsoft/Outlook/Outlook/t.d.sviridova@mrggroup.ru.dat 610748 /mnt/dat/profiles$/tep_la.V2/AppData/Roaming/Microsoft/Outlook/Outlook/teptsova@mrggroup.ru.dat 410844 /mnt/dat/profiles$/tru_ma/Application Data/Microsoft/Outlook/Outlook/ybitki@mrgarant.ru.dat 544272 /mnt/dat/profiles$/vor_ya/Application Data/Microsoft/Outlook/Outlook/y.a.vorontsova@mrggroup.ru.dat 1113804 /mnt/dat/profiles$/zlo_ov/Application Data/Microsoft/Outlook/Outlook/zlotya@mrggroup.ru.dat 21721472 |
#ps fax
![]() PID TTY STAT TIME COMMAND 2 ? S< 0:00 [kthreadd] 3 ? S< 0:00 \_ [migration/0] 4 ? S< 0:05 \_ [ksoftirqd/0] 5 ? S< 0:00 \_ [watchdog/0] 6 ? S< 0:00 \_ [migration/1] 7 ? S< 0:20 \_ [ksoftirqd/1] 8 ? S< 0:00 \_ [watchdog/1] 9 ? S< 0:00 \_ [migration/2] 10 ? S< 0:18 \_ [ksoftirqd/2] ... 31098 ? SN 0:00 \_ (ntlm_auth) --helper-protocol=squid-2.5-ntlmssp 31099 ? SN 0:00 \_ (ntlm_auth) --helper-protocol=squid-2.5-ntlmssp 31100 ? SN 0:00 \_ (ntlm_auth) --helper-protocol=squid-2.5-ntlmssp 31101 ? SN 0:00 \_ (ntlm_auth) --helper-protocol=squid-2.5-ntlmssp 31102 ? SN 0:00 \_ (ntlm_auth) --helper-protocol=squid-2.5-ntlmssp 31103 ? SN 0:00 \_ (ntlm_auth) --helper-protocol=squid-2.5-ntlmssp 31104 ? SN 0:00 \_ (unlinkd) 31229 ? SN 0:01 /usr/local/bin/samsdaemon 17286 ? SNl 0:43 /opt/openfire/jre/bin/java -server -DopenfireHome=/opt/openf 17350 ? SNs 2:20 /sbin/syslogd -u syslogd -j /var/resolv |
#ps fax
PID TTY STAT TIME COMMAND 2 ? S< 0:00 [kthreadd] 3 ? S< 0:00 \_ [migration/0] 4 ? S< 0:05 \_ [ksoftirqd/0] 5 ? S< 0:00 \_ [watchdog/0] 6 ? S< 0:00 \_ [migration/1] 7 ? S< 0:20 \_ [ksoftirqd/1] 8 ? S< 0:00 \_ [watchdog/1] 9 ? S< 0:00 \_ [migration/2] 10 ? S< 0:18 \_ [ksoftirqd/2] ... 31098 ? SN 0:00 \_ (ntlm_auth) --helper-protocol=squid-2.5-ntlmssp 31099 ? SN 0:00 \_ (ntlm_auth) --helper-protocol=squid-2.5-ntlmssp 31100 ? SN 0:00 \_ (ntlm_auth) --helper-protocol=squid-2.5-ntlmssp 31101 ? SN 0:00 \_ (ntlm_auth) --helper-protocol=squid-2.5-ntlmssp 31102 ? SN 0:00 \_ (ntlm_auth) --helper-protocol=squid-2.5-ntlmssp 31103 ? SN 0:00 \_ (ntlm_auth) --helper-protocol=squid-2.5-ntlmssp 31104 ? SN 0:00 \_ (unlinkd) 31229 ? SN 0:01 /usr/local/bin/samsdaemon 17286 ? SNl 0:43 /opt/openfire/jre/bin/java -server -DopenfireHome=/opt/openf 17350 ? SNs 2:20 /sbin/syslogd -u syslogd -j /var/resolv |
#l3
![]() l3 l3_close_session l3mass_upload l3upload l3-agent l3_fix_prompt l3pwd l3-backend l3_save_last_line l3script l3-config l3cd l3shot |
#ps fax | grep l3-a
![]() 11359 pts/2 S+ 0:00 \_ grep l3-a 12491 ? Ss 7:39 l3-agent |
#l3
![]() l3 l3_close_session l3mass_upload l3upload l3-agent l3_fix_prompt l3pwd l3-backend l3_save_last_line l3script l3-config l3cd l3shot |
#ps fax | grep l3-a
11359 pts/2 S+ 0:00 \_ grep l3-a 12491 ? Ss 7:39 l3-agent |
#cat l3-agent
![]() #!/usr/bin/perl -w # # (c) Igor Chubin, igor@chub.in, 2004-2008 # use strict; use POSIX; use Term::VT102; use Text::Iconv; use Time::Local 'timelocal_nocheck'; use IO::Socket; ... send_cache() && unlink($Config{cache}); } sleep($Config{"daemon_sleep_interval"} || 1); } unlink $Config{agent_pidfile}; } } sub init_variables { } |
#cat l3-agent
#!/usr/bin/perl -w # # (c) Igor Chubin, igor@chub.in, 2004-2008 # use strict; use POSIX; use Term::VT102; use Text::Iconv; use Time::Local 'timelocal_nocheck'; use IO::Socket; ... send_cache() && unlink($Config{cache}); } sleep($Config{"daemon_sleep_interval"} || 1); } unlink $Config{agent_pidfile}; } } sub init_variables { } |
#head l3-agent
![]() #!/usr/bin/perl -w # # (c) Igor Chubin, igor@chub.in, 2004-2008 # use strict; use POSIX; use Term::VT102; use Text::Iconv; |
#head l3-agent
#!/usr/bin/perl -w # # (c) Igor Chubin, igor@chub.in, 2004-2008 # use strict; use POSIX; use Term::VT102; use Text::Iconv; |
#exit
|
$vim /etc/l
![]() |
$vim /etc/lil
![]() |
$vim /etc/lilalo/l3config.pm
|
$vim ~/.l3rc
|
$cd /tmp/
|
$l
итого 553 -rw-r--r-- 1 root root 120610 Сен 12 10:00 dcc2 drwxrwxrwt 13 root root 680 Сен 12 10:00 ./ -rw-r--r-- 1 root root 76923 Сен 12 10:00 dcc1 -rw-r--r-- 1 root root 0 Сен 12 10:00 dayup_comp_all_full -rw-rw---- 1 root root 101373 Сен 12 09:58 ytnef_cg_filter.log drwxrwx--- 3 root root 60 Сен 12 09:58 ytnef_cg_filter/ -rw-r--r-- 1 root root 216 Сен 12 09:41 dat4 -rw-r--r-- 1 root root 3164 Сен 12 09:41 dat3 -rw-r--r-- 1 root root 228 Сен 12 09:38 dat2 ... srwxrwxr-x 1 root root 0 Сен 8 15:46 .imspectoricqcookie drwxr-xr-x 2 root root 60 Сен 8 15:46 .winbindd/ lrwxrwxrwx 1 root root 37 Сен 8 15:45 .s.PGSQL.5432 -> /var/lib/pgsql-root/tmp/.s.PGSQL.5432 -rw-r--r-- 1 root root 0 Сен 8 15:45 files.tmp drwxrwxrwt 2 root root 40 Сен 8 15:44 .esd/ drwxrwxrwt 2 root root 40 Сен 8 15:44 .font-unix/ drwxrwxrwt 2 root root 40 Сен 8 15:44 .ICE-unix/ drwxrwxrwt 2 root root 40 Сен 8 15:44 .X11-unix/ drwxr-xr-x 24 root root 680 Июл 5 13:25 ../ -rw-r--r-- 1 su su 151793 Мар 16 2008 lilalo.tar.gz |
$cd lilalo
|
$l
итого 428 drwxrwxrwt 13 root root 680 Сен 12 10:00 ../ drwxr-xr-x 8 su su 860 Сен 9 14:18 ./ -rwxr-xr-x 1 su su 32757 Мар 16 2008 l3-agent drwxr-xr-x 2 su su 100 Мар 13 2008 CVS/ -rwxr-xr-x 1 su su 7522 Мар 13 2008 l3bashrc -rwxr-xr-x 1 su su 78084 Мар 13 2008 l3-frontend -rw-r--r-- 1 su su 5781 Мар 10 2008 l3config.pm -rwxr-xr-x 1 su su 5168 Мар 10 2008 install -rwxr-xr-x 1 su su 234 Мар 10 2008 l3prompt ... -rw-r--r-- 1 su su 1598 Ноя 3 2005 tail-all.pl -rwxr-xr-x 1 su su 47 Ноя 2 2005 l3-report -rwxr-xr-x 1 su su 31413 Ноя 2 2005 lm-report -rw-r--r-- 1 su su 4162 Окт 22 2005 lilalo.kdi drwxr-xr-x 3 su su 160 Май 22 2005 share/ -rw-r--r-- 1 su su 1496 Май 22 2005 FILES -rw-r--r-- 1 su su 452 Май 22 2005 INSTALL -rwxr-xr-x 1 su su 316 Май 22 2005 lm-ssh -rw-r--r-- 1 su su 157 Май 22 2005 taillast.pl -rw-r--r-- 1 su su 111 Май 22 2005 .tarball |
$ls
CVS INSTALL l3-config l3scripts lm-report rebuild-all-logs DELETE l3-agent l3config.pm l3-upload lm-ssh share doc l3-backend l3files LICENSE mysql tail-all.pl FILES l3bashrc l3-frontend lilalo.kdi nohup.out tail-backend.pl HISTORY l3-cgi l3prompt lm PM taillast.pl install l3-cgi-lite l3-report lm-install README TODO |
$less INSTALL
|
$./lm-
![]() lm-install lm-report lm-ssh |
$./lm-install
./lm-install [-d] path... * Use -d to deinstall labmaker * You can specify directory list to install LabMaker as command line parameters or set it in $users_to_install variable in the script Example: Command # ./lm-install /root /home/user installs labmaker to /root and /home/user directories |
$sudo su
|
#./lm-install /root/ /home/su/ /home/kos_aa/
![]() Don't forget to check .bash_profile for .bashrc call LabMaker is installed to /root//.bash_profile LabMaker is installed to /root//.bashrc Don't forget to check .bash_profile for .bashrc call LabMaker is installed to /home/su//.bash_profile LabMaker is installed to /home/su//.bashrc Don't forget to check .bash_profile for .bashrc call LabMaker is installed to /home/kos_aa//.bash_profile LabMaker is installed to /home/kos_aa//.bashrc LabMaker is installed to /bin/vi LabMaker is installed to /usr/bin/vim |
#./lm-install /root/ /home/su/ /home/kos_aa/
![]() Don't forget to check .bash_profile for .bashrc call LabMaker is installed to /root//.bash_profile LabMaker is installed to /root//.bashrc Don't forget to check .bash_profile for .bashrc call LabMaker is installed to /home/su//.bash_profile LabMaker is installed to /home/su//.bashrc Don't forget to check .bash_profile for .bashrc call LabMaker is installed to /home/kos_aa//.bash_profile LabMaker is installed to /home/kos_aa//.bashrc LabMaker is installed to /bin/vi LabMaker is installed to /usr/bin/vim |
#./lm-report
![]() Undefined subroutine &main::init_variables called at ./lm-report line 1162. |
#./lm-report
![]() Undefined subroutine &main::init_variables called at ./lm-report line 1162. |
#exit
|
#!/usr/bin/perl -w # # (c) Igor Chubin, igor@chub.in, 2004-2008 # use strict; use POSIX; use Term::VT102; use Text::Iconv; use Time::Local 'timelocal_nocheck'; use IO::Socket; use lib "/etc/lilalo"; use l3config; our @Command_Lines; our @Command_Lines_Index; our %Diffs; our %Sessions; our %Script_Files; # Информация о позициях в скрипт-файлах, # до которых уже выполнен разбор # и информация о времени модификации файла # $Script_Files{$file}->{size} # $Script_Files{$file}->{tell} our $Killed =0; # В режиме демона -- процесс получил сигнал о завершении sub init_variables; sub main; sub load_diff_files; sub bind_diff; sub extract_commands_from_cline; sub load_command_lines; sub sort_command_lines; sub print_command_lines; sub printq; sub save_cache_stat; sub load_cache_stat; sub print_session; sub load_diff_files { my @pathes = @_; for my $path (@pathes) { my $template = "*.diff"; my @files = <$path/$template>; my $i=0; for my $file (@files) { next if defined($Diffs{$file}); my %diff; # Старый формат имени diff-файла # DEPRECATED if ($file=~m@/(D?[0-9][0-9]?[0-9]?)[^/]*?([0-9]*):([0-9]*):?([0-9]*)@) { $diff{"day"}=$1 || ""; $diff{"hour"}=$2; $diff{"min"}=$3; $diff{"sec"}=$4 || 0; $diff{"uid"} = 0 if $path =~ m@/root/@; print "diff loaded: $diff{day} $diff{hour}:$diff{min}:$diff{sec}\n"; } # Новый формат имени diff-файла elsif ($file =~ m@.*/([^_]*)_([0-9]+)(.*)@) { $diff{"local_session_id"} = $1; $diff{"time"} = $2; $diff{"filename"} = $3; $diff{"filename"} =~ s@_@/@g; $diff{"filename"} =~ s@//@_@g; print "diff loaded: $diff{filename} (time=$diff{time},session=$diff{local_session_id})\n"; } else { next; } # Чтение и изменение кодировки содержимого diff-файла local $/; open (F, "$file") or return "Can't open file $file ($_[0]) for reading"; my $text = <F>; if ($Config{"encoding"} && $Config{"encoding"} !~ /^utf-8$/i) { my $converter = Text::Iconv->new($Config{"encoding"}, "utf-8"); $text = $converter->convert($text); } close(F); $diff{"text"}=$text; $diff{"path"}=$path; $diff{"bind_to"}=""; $diff{"time_range"}=-1; $diff{"index"}=$i; $Diffs{$file} = \%diff; $i++; } } } sub bind_diff { print "Trying to bind diff...\n"; my $cl = shift; my $hour = $cl->{"hour"}; my $min = $cl->{"min"}; my $sec = $cl->{"sec"}; my $min_dt = 10000; if (defined($cl->{"diff"})) { print STDERR "Command ".$cl->{time}." is already bound"; return; } # Загружаем новые diff-файлы # Это нужно делать непосредственно перед привязкой, поскольку diff'ы могли образоваться только что for my $lab_log (split (/\s+/, $Config{"diffs"} || $Config{"input"})) { load_diff_files($lab_log); } my $diff_to_bind; for my $diff_key (keys %Diffs) { my $diff = $Diffs{$diff_key}; next if ($diff->{"local_session_id"} && $cl->{"local_session_id"} && ($cl->{"local_session_id"} ne $diff->{"local_session_id"})); next if ($diff->{"day"} && $cl->{"day"} && ($cl->{"day"} ne $diff->{"day"})); my $dt; if (not $diff->{"time"}) { print STDERR "diff time is 0"; print STDERR join(" ", keys(%$diff)); print STDERR $diff->{text}; } if (not $cl->{"time"}) { print STDERR "cl time is 0"; } if ($diff->{"time"} && $cl->{"time"}) { $dt = $diff->{"time"} - $cl->{"time"} } else { $dt=($diff->{"hour"}-$hour)*3600 +($diff->{"min"}-$min)*60 + ($diff->{"sec"}-$sec); } if ($dt >=0 && $dt < $min_dt && !$diff->{"bind_to"}) { $min_dt = $dt; $diff_to_bind = $diff_key; } } if ($diff_to_bind) { print "Approppriate diff found: dt=$min_dt\n"; $Diffs{$diff_to_bind}->{"bind_to"}=$cl; $cl->{"diff"} = $diff_to_bind; } else { print STDERR "Diff not found\n"; print STDERR "cl{time}",$cl->{time},"\n"; } } sub extract_commands_from_cline # Разобрать командную строку $_[1] и возвратить хэш, содержащий # номер первого появление команды в строке: # команда => первая позиция { my $cline = $_[0]; my @lists = split /\;/, $cline; my @commands = (); for my $list (@lists) { push @commands, split /\|/, $list; } my %commands; my %files; my $i=0; for my $command (@commands) { $command =~ /\s*(\S+)\s*(.*)/; if ($1 && $1 eq "sudo" ) { $commands{"$1"}=$i++; $command =~ s/\s*sudo\s+//; } $command =~ /\s*(\S+)\s*(.*)/; if ($1 && !defined $commands{"$1"}) { $commands{"$1"}=$i++; }; } return %commands; } sub load_command_lines { my $lab_scripts_path = $_[0]; my $lab_scripts_mask = $_[1]; my $cline_re_base = qq' ( (?:\\^?([0-9]*C?)) # exitcode (?:_([0-9]+)_)? # uid (?:_([0-9]+)_) # pid (...?) # day (.?.?) # lab \\s # space separator ([0-9][0-9]):([0-9][0-9]):([0-9][0-9]) # time .\\[50D.\\[K # killing symbols (.*?([\$\#]\\s?)) # prompt (.*) # command line ) '; my $cline_re = qr/$cline_re_base/sx; my $cline_re2 = qr/$cline_re_base$/sx; my $cline_re_v2_base = qq' ( v2[\#] # version ([0-9]+)[\#] # history line number ([0-9]+)[\#] # exitcode ([0-9]+)[\#] # uid ([0-9]+)[\#] # pid ([0-9]+)[\#] # time (.*?)[\#] # pwd .\\[1024D.\\[K # killing symbols (.*?([\$\#]\\s?)) # prompt (.*) # command line ) '; my $cline_re_v2 = qr/$cline_re_v2_base/sx; my $cline_re2_v2 = qr/$cline_re_v2_base$/sx; my $cline_re_v3_base = qq' ( v3[\#] # version .* ) '; my $cline_re_v3 = qr/$cline_re_v3_base/sx; my $cline_re2_v3_base = qq' ( v3[\#] # version ([0-9]+)[\#] # history line number ([0-9]+)[\#] # exitcode ([0-9]+)[\#] # uid ([0-9]+)[\#] # pid ([0-9]+)[\#] # time (.*?)[\#] # pwd (.*?)[\#] # nonce (.*?([\$\#]\\s?)) # prompt (.*) # command line ) '; my $cline_re2_v3 = qr/$cline_re2_v3_base$/sx; my %vt; # Хэш виртуальных терминалов. По одному на каждый сеанс my $cline_vt = Term::VT102->new ( 'cols' => $Config{"terminal_width"}, 'rows' => $Config{"terminal_height"}); my $converter = Text::Iconv->new($Config{"encoding"}, "utf-8") if ($Config{"encoding"} && $Config{"encoding"} !~ /^utf-8$/i); print "Parsing lab scripts...\n" if $Config{"verbose"} =~ /y/; my $file; my $skip_info; my $commandlines_loaded =0; my $commandlines_processed =0; my @lab_scripts = <$lab_scripts_path/$lab_scripts_mask>; for $file (@lab_scripts){ # Пропускаем файл, если он не изменялся со времени нашего предудущего прохода my $size = (stat($file))[7]; next if ($Script_Files{$file} && $Script_Files{$file}->{size} && $Script_Files{$file}->{size} >= $size); my $local_session_id; # Начальное значение идентификатора текущего сеанса определяем из имени скрипта # Впоследствии оно может быть уточнено $file =~ m@.*/([^/]*)\.script$@; $local_session_id = $1; if (not defined($vt{$local_session_id})) { $vt{$local_session_id} = Term::VT102->new ( 'cols' => $Config{"terminal_width"}, 'rows' => $Config{"terminal_height"}); } #Если файл только что появился, #пытаемся найти и загрузить информацию о соответствующей ему сессии if (!$Script_Files{$file}) { my $session_file = $file; $session_file =~ s/\.script/.info/; if (open(SESSION, $session_file)) { local $/; my $data = <SESSION>; close(SESSION); for my $session_data ($data =~ m@<session>(.*?)</session>@sg) { my %session; while ($session_data =~ m@<([^>]*?)>(.*?)</\1>@sg) { $session{$1} = $2; } $local_session_id = $session{"local_session_id"} if $session{"local_session_id"}; $Sessions{$local_session_id}=\%session; } #Загруженную информацию сразу же отправляем в поток print_session($Config{cache}, $local_session_id); } else { die "can't open session file"; } } open (FILE, "$file"); binmode FILE; # Переходим к тому месту, где мы окончили разбор seek (FILE, $Script_Files{$file}->{tell}, 0) if $Script_Files{$file}->{tell}; $Script_Files{$file}->{size} = $size; $Script_Files{$file}->{tell} = 0 unless $Script_Files{$file}->{tell}; $file =~ m@.*/(.*?)-.*@; print "\n+- processing file $file\n| " if $Config{"verbose"} =~/y/; my $tty = $1; my %cl; my $last_output_length=0; my $saved_output; while (<FILE>) { $commandlines_processed++; next if s/^Script started on.*?\n//s; if (/[0-9][0-9]:[0-9][0-9]:[0-9][0-9].\[[0-9][0-9]D.\[K/ && m/$cline_re/) { s/.*\x0d(?!\x0a)//; m/$cline_re2/gs; $commandlines_loaded++; $last_output_length=0; # Previous command my %last_cl = %cl; my $this_line = $1; my $err = $2 || ""; $cl{"local_session_id"} = $local_session_id; # Parse new command $cl{"uid"} = $3; #$cl{"euid"} = $cl{"uid"}; # Если в команде обнаружится sudo, euid поменяем на 0 $cl{"pid"} = $4; $cl{"day"} = $5; $cl{"lab"} = $6; $cl{"hour"} = $7; $cl{"min"} = $8; $cl{"sec"} = $9; #$cl{"fullprompt"} = $10; $cl{"prompt"} = $11; $cl{"raw_cline"} = $12; { use bytes; $cl{"raw_start"} = tell (FILE) - length($this_line); $cl{"raw_output_start"} = tell FILE; } $cl{"raw_file"} = $file; $cl{"err"} = 0; $cl{"output"} = ""; $cl{"tty"} = $tty; $cline_vt->process($cl{"raw_cline"}."\n"); $cl{"cline"} = $cline_vt->row_plaintext (1); $cl{"cline"} =~ s/\s*$//; $cl{"cline"} =~ s/.*?[\#\$]\s*//; $cline_vt->reset(); my %commands = extract_commands_from_cline($cl{"cline"}); #$cl{"euid"}=0 if defined $commands{"sudo"}; my @comms = sort { $commands{$a} cmp $commands{$b} } keys %commands; $cl{"last_command"} = $comms[$#comms] || ""; if ( $Config{"suppress_editors"} =~ /^y/i && grep ($_ eq $cl{"last_command"}, @{$Config{"editors"}}) || $Config{"suppress_pagers"} =~ /^y/i && grep ($_ eq $cl{"last_command"}, @{$Config{"pagers"}}) || $Config{"suppress_terminal"}=~ /^y/i && grep ($_ eq $cl{"last_command"}, @{$Config{"terminal"}}) ) { $cl{"suppress_output"} = "1"; } else { $cl{"suppress_output"} = "0"; } $skip_info = 0; print " ",$cl{"last_command"}; if (grep ($_ eq $last_cl{"last_command"}, @{$Config{"editors"}})) { bind_diff(\%last_cl); } # Error code $last_cl{"raw_end"} = $cl{"raw_start"}; $last_cl{"err"}=$err; $last_cl{"err"}=130 if $err eq "^C"; # Output if (!$last_cl{"suppress_output"} || $last_cl{"err"}) { for (my $i=0; $i<$Config{"terminal_height"}; $i++) { my $line= $vt{$local_session_id}->row_plaintext($i); next if !defined ($line) ; #|| $line =~ /^\s*$/; $line =~ s/\s*$//; $line .= "\n" unless $line =~ /^\s*$/; $last_cl{"output"} .= $line; } } else { $last_cl{"output"}= ""; } $vt{$local_session_id}->reset(); # Save if (!$Config{"lab"} || $cl{"lab"} eq $Config{"lab"}) { # Changing encoding for (keys %last_cl) { next if /raw/; $last_cl{$_} = $converter->convert($last_cl{$_}) if ($Config{"encoding"} && $Config{"encoding"} !~ /^utf-8$/i); } push @Command_Lines, \%last_cl; # Сохранение позиции в файле, до которой выполнен # успешный разбор $Script_Files{$file}->{tell} = $last_cl{raw_end}; } next; } elsif (m/$cline_re_v2/ || m/$cline_re_v3/) { # Разбираем командную строку версии 2 my $before=$_; s/.*\x0d(?!\x0a)//; my $re; if (m/$cline_re_v2/) { $re=$cline_re2_v2; } else { s/.\[1K.\[10D//gs; $re=$cline_re2_v3; print STDERR "... $_ ...\n"; } m/$re/gs; $commandlines_loaded++; $last_output_length=0; # Previous command my %last_cl = %cl; $cl{"local_session_id"} = $local_session_id; # Parse new command my $this_line = $1; $cl{"history"} = $2; my $err = $3; $cl{"uid"} = $4; #$cl{"euid"} = $cl{"uid"}; # Если в команде обнаружится sudo, euid поменяем на 0 $cl{"pid"} = $5; $cl{"time"} = $6; $cl{"pwd"} = $7; $cl{"nonce"} = $8; #$cl{"fullprompt"} = $8; $cl{"prompt"} = $10; #$cl{"raw_cline"}= $10; $cl{"raw_cline"}= $before; { use bytes; $cl{"raw_start"} = tell (FILE) - length($before); $cl{"raw_output_start"} = tell FILE; } $cl{"raw_file"} = $file; $cl{"err"} = 0; $cl{"output"} = ""; #$cl{"tty"} = $tty; $cline_vt->process($cl{"raw_cline"}."\n"); $cl{"cline"} = $cline_vt->row_plaintext (1); $cl{"cline"} =~ s/\s*$//; $cl{"cline"} =~ s/.*?[\#\$]\s*//; $cline_vt->reset(); print STDERR "cline=".$cl{"cline"}."<<\n"; my %commands = extract_commands_from_cline($cl{"cline"}); #$cl{"euid"} = 0 if defined $commands{"sudo"}; my @comms = sort { $commands{$a} cmp $commands{$b} } keys %commands; $cl{"last_command"} = $comms[$#comms] || ""; print STDERR "last_command=".$cl{"last_command"}."<<\n"; if ( $Config{"suppress_editors"} =~ /^y/i && grep ($_ eq $cl{"last_command"}, @{$Config{"editors"}}) || $Config{"suppress_pagers"} =~ /^y/i && grep ($_ eq $cl{"last_command"}, @{$Config{"pagers"}}) || $Config{"suppress_terminal"}=~ /^y/i && grep ($_ eq $cl{"last_command"}, @{$Config{"terminal"}}) ) { $cl{"suppress_output"} = "1"; } else { $cl{"suppress_output"} = "0"; } $skip_info = 0; if ($Config{verbose} =~ /y/i) { print "\n| " if $commandlines_loaded % 5 == 1; print " ",$cl{"last_command"}; } if (defined($last_cl{time}) && grep ($_ eq $last_cl{"last_command"}, @{$Config{"editors"}})) { bind_diff(\%last_cl); } # Error code $last_cl{"err"}=$err; $last_cl{"raw_end"} = $cl{"raw_start"}; # Output if (!$last_cl{"suppress_output"} || $last_cl{"err"}) { $last_cl{"output"}=$saved_output; for (my $i=0; $i<$Config{"terminal_height"}; $i++) { my $line= $vt{$local_session_id}->row_plaintext($i); next if !defined ($line) ; #|| $line =~ /^\s*$/; $line =~ s/\s*$//; $line .= "\n" unless $line =~ /^\s*$/; $last_cl{"output"} .= $line; } } else { $last_cl{"output"}= ""; } $vt{$local_session_id}->reset(); $saved_output=""; # Changing encoding for (keys %last_cl) { next if /raw/; if ($Config{"encoding"} && $Config{"encoding"} !~ /^utf-8$/i) { $last_cl{$_} = $converter->convert($last_cl{$_}) } } if (defined($last_cl{time})) { print STDERR "push id=".$last_cl{time}."\n"; push @Command_Lines, \%last_cl; # Сохранение позиции в файле, до которой выполнен # успешный разбор $Script_Files{$file}->{tell} = $last_cl{raw_end}; } next; } if (($commandlines_processed%100) == 0) { # Каждые сто строк обнуляем терминал и переносим вывод из него в кэш # Output for (my $i=0; $i<$Config{"terminal_height"}; $i++) { my $line= $vt{$local_session_id}->row_plaintext($i); next if !defined ($line) ; #|| $line =~ /^\s*$/; $line =~ s/\s*$//; $line .= "\n" unless $line =~ /^\s*$/; $saved_output .= $line; } $vt{$local_session_id}->reset(); $last_output_length=0; } # Иначе, это строка вывода $last_output_length+=length($_); #if (!$cl{"suppress_output"} || $last_output_length < 5000) { if ($last_output_length < 50000) { $vt{$local_session_id}->process("$_"."\n") } else { if (!$skip_info && defined($cl{last_command})) { print "($cl{last_command})"; $skip_info = 1; } } } close(FILE); } if ($Config{"verbose"} =~ /y/) { print "\n`- finished.\n" ; print "Lines loaded: $commandlines_processed\n"; print "Command lines: $commandlines_loaded\n"; } } sub sort_command_lines { print "Sorting command lines..." if $Config{"verbose"} =~ /y/; # Sort Command_Lines # Write Command_Lines to Command_Lines_Index my @index; for (my $i=0;$i<=$#Command_Lines;$i++) { $index[$i]=$i; } @Command_Lines_Index = sort { defined($Command_Lines[$index[$a]]->{"time"}) && defined($Command_Lines[$index[$b]]->{"time"}) ? $Command_Lines[$index[$a]]->{"time"} <=> $Command_Lines[$index[$b]]->{"time"} : defined($Command_Lines[$index[$a]]->{"day"}) && defined($Command_Lines[$index[$b]]->{"day"}) && defined($Command_Lines[$index[$a]]->{"hour"}) && defined($Command_Lines[$index[$b]]->{"hour"}) && defined($Command_Lines[$index[$a]]->{"min"}) && defined($Command_Lines[$index[$b]]->{"min"}) && defined($Command_Lines[$index[$a]]->{"sec"}) && defined($Command_Lines[$index[$b]]->{"sec"}) ? $Command_Lines[$index[$a]]->{"day"} cmp $Command_Lines[$index[$b]]->{"day"} || $Command_Lines[$index[$a]]->{"hour"} <=> $Command_Lines[$index[$b]]->{"hour"} || $Command_Lines[$index[$a]]->{"min"} <=> $Command_Lines[$index[$b]]->{"min"} || $Command_Lines[$index[$a]]->{"sec"} <=> $Command_Lines[$index[$b]]->{"sec"} : 0 } @index; print "finished\n" if $Config{"verbose"} =~ /y/; } sub printq { my $TO = shift; my $text = join "", @_; $text =~ s/&/&/g; $text =~ s/</</g; $text =~ s/>/>/g; print $TO $text; } =cut Вывести результат обработки журнала. =cut sub print_command_lines { my $output_filename=$_[0]; open(OUT, ">>", $output_filename) or die "Can't open $output_filename for writing\n"; my $cl; my $in_range=0; for my $i (@Command_Lines_Index) { $cl = $Command_Lines[$i]; if ($Config{"from"} && $cl->{"cline"} =~ /$Config{"signature"}\s*$Config{"from"}/) { $in_range=1; next; } if ($Config{"to"} && $cl->{"cline"} =~ /$Config{"signature"}\s*$Config{"to"}/) { $in_range=0; next; } next if ($Config{"from"} && $Config{"to"} && !$in_range) || ($Config{"skip_empty"} =~ /^y/i && $cl->{"cline"} =~ /^\s*$/ ) || ($Config{"skip_wrong"} =~ /^y/i && $cl->{"err"} != 0) || ($Config{"skip_interrupted"} =~ /^y/i && $cl->{"err"} == 130); # Вырезаем из вывода только нужное количество строк my $output=""; if (!grep ($_ eq $cl->{"last_command"}, @{$Config{"full_output_commands"}}) && ($Config{"head_lines"} || $Config{"tail_lines"})) { # Partialy output my @lines = split '\n', $cl->{"output"}; # head my $mark=1; for (my $i=0; $i<= $#lines && $i < $Config{"cache_head_lines"}; $i++) { $output .= $lines[$i]."\n"; } # tail my $start=$#lines-$Config{"cache_tail_lines"}+1; if ($start < 0) { $start=0; $mark=0; } if ($start < $Config{"cache_head_lines"}) { $start=$Config{"cache_head_lines"}; $mark=0; } $output .= $Config{"skip_text"}."\n" if $mark; for ($i=$start; $i<= $#lines; $i++) { $output .= $lines[$i]."\n"; } } else { # Full output $output .= $cl->{"output"}; } # Совместимость с labmaker # Переводим в секунды Эпохи # В labmaker'е данные хранились в неудобной форме: hour, min, sec, day of year # Информация о годе отсутствовала # Её можно внести: # Декабрь 2004 год; остальные -- 2005 год. my $year = 2005; #$year = 2004 if ( $cl->{day} > 330 ); $year = $Config{year} if $Config{year}; # timelocal( $sec, $min, $hour, $mday,$mon,$year); $cl->{time} ||= timelocal_nocheck($cl->{sec},$cl->{min},$cl->{hour},$cl->{day},0,$year); # Начинаем вывод команды print OUT "<command>\n"; print OUT "<l3cd>$Config{l3cd}</l3cd>\n" if $Config{"l3cd"}; for my $element (qw( local_session_id history uid pid time pwd raw_start raw_output_start raw_end raw_file tty err last_command history nonce )) { next unless defined($cl->{"$element"}); print OUT "<$element>".$cl->{$element}."</$element>\n"; } for my $element (qw( prompt cline )) { next unless defined($cl->{"$element"}); print OUT "<$element>"; printq(\*OUT,$cl->{"$element"}); print OUT "</$element>\n"; } #note #note_title print OUT "<output>"; printq(\*OUT,$output); print OUT "</output>\n"; if ($cl->{"diff"}) { print OUT "<diff>"; printq(\*OUT,${$Diffs{$cl->{"diff"}}}{"text"}); print OUT "</diff>\n"; } print OUT "</command>\n"; } close(OUT); } sub print_session { my $output_filename = $_[0]; my $local_session_id = $_[1]; return if not defined($Sessions{$local_session_id}); print "printing session info. session id = ".$local_session_id."\n" if $Config{verbose} =~ /y/; open(OUT, ">>", $output_filename) or die "Can't open $output_filename for writing\n"; print OUT "<session>\n"; print OUT "<l3cd>$Config{l3cd}</l3cd>\n" if $Config{"l3cd"}; my %session = %{$Sessions{$local_session_id}}; for my $key (keys %session) { print OUT "<$key>".$session{$key}."</$key>\n"; print " ".$key,"\n"; } print OUT "</session>\n"; close(OUT); } sub send_cache { # Если в кэше что-то накопилось, # попытаемся отправить это на сервер # my $cache_was_sent=0; if (open(CACHE, $Config{cache})) { local $/; my $cache = <CACHE>; close(CACHE); my $socket = IO::Socket::INET->new( PeerAddr => $Config{backend_address}, PeerPort => $Config{backend_port}, proto => "tcp", Type => SOCK_STREAM ); if ($socket) { print $socket $cache; close($socket); $cache_was_sent = 1; } } return $cache_was_sent; } sub save_cache_stat { open (CACHE, ">$Config{cache_stat}"); for my $f (keys %Script_Files) { print CACHE "$f\t",$Script_Files{$f}->{size},"\t",$Script_Files{$f}->{tell},"\n"; } close(CACHE); } sub load_cache_stat { if (open (CACHE, "$Config{cache_stat}")) { while(<CACHE>) { chomp; my ($f, $size, $tell) = split /\t/; $Script_Files{$f}->{size} = $size; $Script_Files{$f}->{tell} = $tell; } close(CACHE); }; } main(); sub process_was_killed { $Killed = 1; } sub reload { init_config; } sub main { $| = 1; init_variables(); init_config(); if ($Config{"mode"} ne "daemon") { # В нормальном режиме работы нужно # считать скрипты, обработать их и записать # результат выполнения в результирующий файл. # После этого завершить работу. # Очистим кэш-файл, если он существовал if (open (CACHE, ">", $Config{"cache"})) { close(CACHE); }; load_command_lines($Config{"input"}, $Config{"input_mask"}); sort_command_lines; #process_command_lines; print_command_lines($Config{"cache"}); } else { if (open(PIDFILE, $Config{agent_pidfile})) { my $pid = <PIDFILE>; close(PIDFILE); if ($^O eq 'linux' && $pid &&(! -e "/proc/$pid" || !`grep $Config{"l3-agent"} /proc/$pid/cmdline && grep "uid:.*\b$<\b" /proc/$pid/status`)) { print "Removing stale pidfile\n"; unlink $Config{agent_pidfile} or die "Can't remove stale pidfile ". $Config{agent_pidfile}. " : $!"; } elsif ($^O eq 'freebsd' && defined($pid) && $pid ne "" && not `ps axo uid,pid,command | grep '$< $pid $Config{"l3-agent"}' | grep -v grep 2> /dev/null`) { print "Removing stale pidfile\n"; unlink $Config{agent_pidfile} or die "Can't remove stale pidfile ". $Config{agent_pidfile}. " : $!"; } elsif ($^O eq 'linux' || $^O eq 'freebsd' ) { print "l3-agent is already running: pid=$pid; pidfile=$Config{agent_pidfile}\n"; exit(0); } else { print "Unknown operating system"; exit(0); } } if ($Config{detach} =~ /^y/i) { #$Config{verbose} = "no"; my $pid = fork; exit if $pid; die "Couldn't fork: $!" unless defined ($pid); open(PIDFILE, ">", $Config{agent_pidfile}) or die "Can't open pidfile ". $Config{agent_pidfile}. " for wrting: $!"; print PIDFILE $$; close(PIDFILE); for my $handle (*STDIN, *STDOUT, *STDERR) { open ($handle, "+<", "/dev/null") or die "can't reopen $handle to /dev/null: $!" } POSIX::setsid() or die "Can't start a new session: $!"; $0 = $Config{"l3-agent"}; $SIG{INT} = $SIG{TERM} = \&process_was_killed; $SIG{HUP} = \&reload; } while (not $Killed) { @Command_Lines = (); @Command_Lines_Index = (); load_cache_stat(); load_command_lines($Config{"input"}, $Config{"input_mask"}); if (@Command_Lines) { sort_command_lines; #process_command_lines; print_command_lines($Config{"cache"}); } save_cache_stat(); if (-e $Config{cache} && (stat($Config{cache}))[7]) { send_cache() && unlink($Config{cache}); } sleep($Config{"daemon_sleep_interval"} || 1); } unlink $Config{agent_pidfile}; } } sub init_variables { }
Время первой команды журнала | 07:34:01 2011- 9-12 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
Время последней команды журнала | 08:01:46 2011- 9-12 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
Количество командных строк в журнале | 46 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
Процент команд с ненулевым кодом завершения, % | 13.04 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
Процент синтаксически неверно набранных команд, % | 0.00 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
Суммарное время работы с терминалом *, час | 0.46 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
Количество командных строк в единицу времени, команда/мин | 1.66 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
Частота использования команд |
|
В журнал автоматически попадают все команды, данные в любом терминале системы.
Для того чтобы убедиться, что журнал на текущем терминале ведётся, и команды записываются, дайте команду w. В поле WHAT, соответствующем текущему терминалу, должна быть указана программа script.
Команды, при наборе которых были допущены синтаксические ошибки, выводятся перечёркнутым текстом:
$ l s-l bash: l: command not found |
Если код завершения команды равен нулю, команда была выполнена без ошибок. Команды, код завершения которых отличен от нуля, выделяются цветом.
$ test 5 -lt 4 |
Команды, ход выполнения которых был прерван пользователем, выделяются цветом.
$ find / -name abc find: /home/devi-orig/.gnome2: Keine Berechtigung find: /home/devi-orig/.gnome2_private: Keine Berechtigung find: /home/devi-orig/.nautilus/metafiles: Keine Berechtigung find: /home/devi-orig/.metacity: Keine Berechtigung find: /home/devi-orig/.inkscape: Keine Berechtigung ^C |
Команды, выполненные с привилегиями суперпользователя, выделяются слева красной чертой.
# id uid=0(root) gid=0(root) Gruppen=0(root) |
Изменения, внесённые в текстовый файл с помощью редактора, запоминаются и показываются в журнале в формате ed. Строки, начинающиеся символом "<", удалены, а строки, начинающиеся символом ">" -- добавлены.
$ vi ~/.bashrc
|
Для того чтобы изменить файл в соответствии с показанными в диффшоте изменениями, можно воспользоваться командой patch. Нужно скопировать изменения, запустить программу patch, указав в качестве её аргумента файл, к которому применяются изменения, и всавить скопированный текст:
$ patch ~/.bashrc |
Для того чтобы получить краткую справочную информацию о команде, нужно подвести к ней мышь. Во всплывающей подсказке появится краткое описание команды.
Если справочная информация о команде есть, команда выделяется голубым фоном, например: vi. Если справочная информация отсутствует, команда выделяется розовым фоном, например: notepad.exe. Справочная информация может отсутствовать в том случае, если (1) команда введена неверно; (2) если распознавание команды LiLaLo выполнено неверно; (3) если информация о команде неизвестна LiLaLo. Последнее возможно для редких команд.
Большие, в особенности многострочные, всплывающие подсказки лучше всего показываются браузерами KDE Konqueror, Apple Safari и Microsoft Internet Explorer. В браузерах Mozilla и Firefox они отображаются не полностью, а вместо перевода строки выводится специальный символ.
Время ввода команды, показанное в журнале, соответствует времени начала ввода командной строки, которое равно тому моменту, когда на терминале появилось приглашение интерпретатора
Имя терминала, на котором была введена команда, показано в специальном блоке. Этот блок показывается только в том случае, если терминал текущей команды отличается от терминала предыдущей.
Вывод не интересующих вас в настоящий момент элементов журнала, таких как время, имя терминала и других, можно отключить. Для этого нужно воспользоваться формой управления журналом вверху страницы.
Небольшие комментарии к командам можно вставлять прямо из командной строки. Комментарий вводится прямо в командную строку, после символов #^ или #v. Символы ^ и v показывают направление выбора команды, к которой относится комментарий: ^ - к предыдущей, v - к следующей. Например, если в командной строке было введено:
$ whoami
user
$ #^ Интересно, кто я?в журнале это будет выглядеть так:
$ whoami
user
Интересно, кто я? |
Если комментарий содержит несколько строк, его можно вставить в журнал следующим образом:
$ whoami
user
$ cat > /dev/null #^ Интересно, кто я?
Программа whoami выводит имя пользователя, под которым мы зарегистрировались в системе. - Она не может ответить на вопрос о нашем назначении в этом мире.В журнале это будет выглядеть так:
$ whoami user
|
Комментарии, не относящиеся непосредственно ни к какой из команд, добавляются точно таким же способом, только вместо симолов #^ или #v нужно использовать символы #=
1 2 3 4Группы команд, выполненных на разных терминалах, разделяются специальной линией. Под этой линией в правом углу показано имя терминала, на котором выполнялись команды. Для того чтобы посмотреть команды только одного сенса, нужно щёкнуть по этому названию.
LiLaLo (L3) расшифровывается как Live Lab Log.
Программа разработана для повышения эффективности обучения Unix/Linux-системам.
(c) Игорь Чубин, 2004-2008