# HG changeset patch # User devi # Date 1131737389 -7200 # Node ID 196c82b6e53807855f1249ede095b444a6513891 # Parent f5f07049bd4f4bd923d7dd7142dd152fcd065e6a l3-cgi: * Сделана поддержка кодировок клиента отличных от utf-8 (пока что почему-то не работает) * Сделана поддержка комментирования из самой командной строки. Комментарии вставлюятся с помощью символов #^, #v или #= Комментарии записываются в элементы note и note_title l3-frontend: * Сделана поддержка комментирования из самой командной строки. Комментарии вставлюятся с помощью символов #^, #v или #= * Вместо использования программы mywi-client, обращение к mywi-серверу выполняется самостоятельно * Выполняется разбор команды с целью выявления новых команд, ведения статистики, генерирования подсказок и т.д. * Во всплывающих командах к подсказкам выводится информация от mywi * Выводится статистическая информация о журнале "Время первой команды журнала" "Время последней команды журнала" "Количество командных строк в журнале" "Процент команд с кодом ненулевым кодом завершения, %" "Суммарное время работы с терминалом *, час" "Количество командных строк в единицу времени, команда/мин" "Частота использования команд" "Частота использования команд" "Частота использования этих команд < 0.5%" * В заголовке страницы выводится информация о курсе и имя слушателя * Расшифровка к информации о курсе выводится только если есть сама информация * В оглавлении учитваются пометки notes, вставленные с помощью #= * Добавлена справка по использованию журнала Новые параметры: show_notes - нужно ли показывать заметки "notes" > note_width - ширина заметок "notes" mywi_server - IP-адрес сервера mywi mywi_port - порт сервера mywi stat_inactivity_interval - при подсчёте времени работы с терминалом, интервалы превышающие какую длительность не должны учитываться, сек diff -r f5f07049bd4f -r 196c82b6e538 l3-agent --- a/l3-agent Tue Nov 08 12:16:20 2005 +0200 +++ b/l3-agent Fri Nov 11 21:29:49 2005 +0200 @@ -543,9 +543,10 @@ if (!$last_cl{"suppress_output"} || $last_cl{"err"}) { for (my $i=0; $i<$Config{"terminal_height"}; $i++) { my $line= $vt->row_plaintext($i); - next if !defined ($line) || $line =~ /^\s*$/; + next if !defined ($line) ; #|| $line =~ /^\s*$/; $line =~ s/\s*$//; - $last_cl{"output"} .= $line."\n"; + $line .= "\n" unless $line =~ /^\s*$/; + $last_cl{"output"} .= $line; } } else { @@ -690,6 +691,13 @@ $Files_Stat{$file}++; } } + + #if ($$cl->{cline}=~ /#\^(.*)/) { + # my $j=$i-1; + # $j-- while ($j >=0 && $Command_Lines[$j]->{tty} ne $$cl->{tty}); + # $Command_Lines[$j]->{note_title}="Замечание"; + # $Command_Lines[$j]->{note}="$1"; + #} } } @@ -773,7 +781,7 @@ # Full output $output .= $cl->{"output"}; } - $output .= "^C\n" if ($cl->{"err"} eq "130"); + #$output .= "^C\n" if ($cl->{"err"} eq "130"); # Совместимость с labmaker @@ -825,6 +833,16 @@ printq(\*OUT,${$Diffs{$cl->{"diff"}}}{"text"}); print OUT "\n"; } + if ($cl->{"note"}) { + print OUT ""; + printq(\*OUT,$cl->{"note"}); + print OUT "\n"; + } + if ($cl->{"note_title"}) { + print OUT ""; + printq(\*OUT,$cl->{"note_title"}); + print OUT "\n"; + } print OUT "\n"; } diff -r f5f07049bd4f -r 196c82b6e538 l3-cgi --- a/l3-cgi Tue Nov 08 12:16:20 2005 +0200 +++ b/l3-cgi Fri Nov 11 21:29:49 2005 +0200 @@ -72,6 +72,13 @@ print "Template to load files: ".$l3config::Config{"path_classes"}."*".$l3config::Config{"class_suffix"}."\n" } } +elsif ($ENV{PATH_INFO} eq "/current") { + open (FRONTEND, "./l3-frontend --output - --show_comments no |"); + while () { + print; + } + close(FRONTEND); +} else { # Вызов производится по URL my ($skip, $course, $host, $user) = split /\//,$ENV{PATH_INFO},4; @@ -88,6 +95,7 @@ "--course-code" => $XMLTraining->{course}, "--course-date" => $XMLTraining->{date}, "--backend_datafile" => "/var/lilalo/lablogs-xml/$course/$host/$user.xml", + "--encoding" => $XMLTraining->{host}->{$host}->{charset}, ); open (FRONTEND, "./l3-frontend ".join(" ",map("\"$_\"",@args))." |"); diff -r f5f07049bd4f -r 196c82b6e538 l3-frontend --- a/l3-frontend Tue Nov 08 12:16:20 2005 +0200 +++ b/l3-frontend Fri Nov 11 21:29:49 2005 +0200 @@ -1,9 +1,15 @@ #!/usr/bin/perl -w +use IO::Socket; use lib '.'; use l3config; +use locale; our @Command_Lines; +our @Command_Lines_Index; +our %Commands_Description; +our %Args_Description; +our $Mywi_Socket; # vvv Инициализация переменных выполняется процедурой init_variables our @Day_Name; @@ -13,12 +19,18 @@ our %Elements_Visibility; # ^^^ +our %Stat; +our %CommandsFDistribution; # Сколько раз в журнале встречается какая команда + sub search_buy; sub make_comment; sub load_command_lines_from_xml; sub print_command_lines; +sub sort_command_lines; +sub process_command_lines; sub init_variables; sub main; +sub collapse_list($); main(); @@ -29,8 +41,12 @@ init_variables(); init_config(); + open_mywi_socket; load_command_lines_from_xml($Config{"backend_datafile"}); + sort_command_lines; + process_command_lines; print_command_lines($Config{"output"}); + close_mywi_socket; } @@ -44,62 +60,139 @@ $Search_Machines{$sm}->{"icon"}."' border='0'/>"; } +sub extract_from_cline +# Разобрать командную строку $_[1] и возвратить хэш, содержащий +# номер первого появление команды в строке: +# команда => первая позиция +{ + my $what = $_[0]; + my $cline = $_[1]; + my @lists = split /\;/, $cline; + + + my @commands = (); + for my $list (@lists) { + push @commands, split /\|/, $list; + } + + my %commands; + my %args; + my $i=0; + for my $command (@commands) { + $command =~ s@^\s*\S+/@@; + $command =~ /\s*(\S+)\s*(.*)/; + if ($1 && $1 eq "sudo" ) { + $commands{"$1"}=$i++; + $command =~ s/\s*sudo\s+//; + } + $command =~ s@^\s*\S+/@@; + $command =~ /\s*(\S+)\s*(.*)/; + if ($1 && !defined $commands{"$1"}) { + $commands{"$1"}=$i++; + }; + if ($2) { + my $args = $2; + my @args = split (/\s+/, $args); + for my $a (@args) { + $args{"$a"}=$i++ + if !defined $args{"$a"}; + }; + + + } + } + + if ($what eq "commands") { + return \%commands; + } else { + return \%args; + } + +} + +sub open_mywi_socket +{ + $Mywi_Socket = IO::Socket::INET->new( + PeerAddr => $Config{mywi_server}, + PeerPort => $Config{mywi_port}, + Proto => "tcp", + Type => SOCK_STREAM); +} + +sub close_mywi_socket +{ + close ($Mywi_Socket); +} + + +sub mywi_client +{ + my $query = $_[0]; + my $mywi; + + open_mywi_socket; + if ($Mywi_Socket) { + local $| = 1; + local $/ = ""; + print $Mywi_Socket $query."\n"; + $mywi = <$Mywi_Socket>; + $mywi = "" if $mywi =~ /nothing app/; + } + close_mywi_socket; + return $mywi; +} + sub make_comment { - my $commands = $_[0]; - my $files = $_[1]; - chomp $commands; - chomp $files; - return if (!$commands && !$files); + my $cline = $_[0]; + #my $files = $_[1]; - my $comment=""; + my @comments=(); + my @commands = keys %{extract_from_cline("commands", $cline)}; + my @args = keys %{extract_from_cline("args", $cline)}; + return if (!@commands && !@args); + #return "commands=".join(" ",@commands)."; files=".join(" ",@files); # Commands - for my $command (split /\s+/,$commands) { + for my $command (@commands) { $command =~ s/'//g; - my $description=""; - eval { $description=`/home/devi/bin/mywi-client '$command'`; } ; - $description = join ("
\n", grep(/\([18]\)/, split(/\n/, $description))); - $description =~ s/.*?-//; - next if $description =~ /^\s*$/; - - my $query=$command." ".$Config{"keywords"}; - $query =~ s/\ /+/g; - my $search= search_by("opennet",$query). - search_by("local",$command). - search_by("google",$query); + $CommandsFDistribution{$command}++; + if (!$Commands_Description{$command}) { + my $mywi; + $mywi = mywi_client ($command); + $mywi = join ("\n", grep(/\([18]\)/, split(/\n/, $mywi))); + $mywi =~ s/\s+/ /; + if ($mywi !~ /^\s*$/) { + $Commands_Description{$command} = $mywi; + } + else { + next; + } + } - $comment .= "$command". - "$search". - "". - "$description"; + push @comments, $Commands_Description{$command}; } + return join(" \n", @comments); # Files - for my $file (split /\s+/,$files) { - $file =~ s@.*/@@; - $file =~ s/'//g; - next if $file =~ /^\s*$/; - next if $file =~ /^-/; - - my $description=`mywi '$file'`; - $description = join ("
\n", grep(/\(5\)/, split(/\n/, $description))); - next if $description =~ /^\s*$/; + for my $arg (@args) { + $arg =~ s/'//g; + if (!$Args_Description{$arg}) { + my $mywi; + $mywi = mywi_client ($arg); + $mywi = join ("\n", grep(/\([5]\)/, split(/\n/, $mywi))); + $mywi =~ s/\s+/ /; + if ($mywi !~ /^\s*$/) { + $Args_Description{$arg} = $mywi; + } + else { + next; + } + } - my $query=$file." ".$Config{"files_keywords"}; - $query =~ s/\ /+/g; - my $search= search_by("opennet",$query). - search_by("local",$file). - search_by("google",$query); - - $comment .= "$file". - "$search". - "". - "$description"; + push @comments, $Args_Description{$arg}; } - - return $comment; } =cut @@ -130,6 +223,123 @@ } } +sub sort_command_lines +{ + # 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 { + $Command_Lines[$index[$a]]->{"time"} <=> $Command_Lines[$index[$b]]->{"time"} + } @index; + +} + +sub process_command_lines +{ + for my $i (@Command_Lines_Index) { + + my $cl = \$Command_Lines[$i]; + @{${$cl}->{"new_commands"}} =(); + @{${$cl}->{"new_files"}} =(); + $$cl->{"class"} = ""; + + if ($$cl->{"err"}) { + $$cl->{"class"}="wrong"; + $$cl->{"class"}="interrupted" + if ($$cl->{"err"} eq 130); + } + if (!$$cl->{"euid"}) { + $$cl->{"class"}.="_root"; + } + +#tab# my @tab_words=split /\s+/, $$cl->{"output"}; +#tab# my $last_word= $$cl->{"cline"} =~ /(\S*)$/; +#tab# $last_word =~ s@.*/@@; +#tab# my $this_is_tab=1; +#tab# +#tab# if ($last_word && @tab_words >2) { +#tab# for my $tab_words (@tab_words) { +#tab# if ($tab_words !~ /^$last_word/) { +#tab# $this_is_tab=0; +#tab# last; +#tab# } +#tab# } +#tab# } +#tab# $$cl->{"class"}="tab" if $this_is_tab; + + +# if ( !$$cl->{"err"}) { +# # Command does not contain mistakes +# +# my %commands = extract_from_cline("commands", ${$cl}->{"cline"}); +# my %files = extract_from_cline("files", ${$cl}->{"cline"}); +# +# # Searching for new commands only +# for my $command (keys %commands) { +# if (!defined $Commands_Stat{$command}) { +# push @{$$cl->{new_commands}}, $command; +# } +# $Commands_Stat{$command}++; +# } +# +# for my $file (keys %files) { +# if (!defined $Files_Stat{$file}) { +# push @{$$cl->{new_files}}, $file; +# } +# $Files_Stat{$file}++; +# } +# } + + if ($$cl->{cline}=~ m@cat[^#]*#([\^=v])\s*(.*)@) { + if ($1 eq "=") { + $$cl->{"class"} = "note"; + $$cl->{"note"} = $$cl->{"output"}; + $$cl->{"note_title"} = $2; + } + else { + my $j = $i; + if ($1 eq "^") { + $j--; + $j-- while ($j >=0 && $Command_Lines[$j]->{tty} ne $$cl->{tty} || !$Command_Lines[$j]); + } + elsif ($1 eq "v") { + $j++; + $j++ while ($j <= @Command_Lines && $Command_Lines[$j]->{tty} ne $$cl->{tty} || !$Command_Lines[$j]); + } + $Command_Lines[$j]->{note_title}="$2"; + $Command_Lines[$j]->{note}=$$cl->{output}; + $$cl=0; + } + } + elsif ($$cl->{cline}=~ /#([\^=v])(.*)/) { + if ($1 eq "=") { + $$cl->{"class"} = "note"; + $$cl->{"note"} = $2; + } + else { + my $j=$i; + if ($1 eq "^") { + $j--; + $j-- while ($j >=0 && (!$Command_Lines[$j] || $Command_Lines[$j]->{tty} ne $$cl->{tty})); + } + elsif ($1 eq "v") { + $j++; + $j++ while ($j <= @Command_Lines && $Command_Lines[$j]->{tty} ne $$cl->{tty} || !$Command_Lines[$j]); + } + $Command_Lines[$j]->{note}="$2"; + $$cl=0; + } + } + } + +} + + =cut Процедура print_command_lines выводит HTML-представление разобранного lab-скрипта. @@ -152,7 +362,8 @@ # Результат выполнения процедуры равен # join("", @Result{header,body,stat,help,about,footer}) my %Result; - my $toc =""; # Хранит оглавление по дням + my @toc; # Хранит оглавление + my $note_number=0; $Result{"body"} = "\n"; @@ -161,7 +372,12 @@ my $last_day=""; my $in_range=0; - for my $cl (@Command_Lines) { + my $i=0; + for my $k (@Command_Lines_Index) { + + my $cl=$Command_Lines[$Command_Lines_Index[$i++]]; + + next unless $cl; if ($Config{"from"} && $cl->{"cline"} =~ /$Config{"signature"}\s*$Config{"from"}/) { $in_range=1; @@ -182,6 +398,20 @@ #my @new_commands=@{$cl->{"new_commands"}}; #my @new_files=@{$cl->{"new_files"}}; + if ($cl->{class} eq "note") { + my $note = $cl->{note}; + $note = join ("\n", map ("

$_

", split (/-\n/, $note))); + $Result{"body"} .= ""; + + if ($cl->{note_title}) { + push @{$toc[@toc]},"".$cl->{note_title}.""; + $note_number++; + } + next; + } + my $cl_class="cline"; my $out_class="output"; if ($cl->{"class"}) { @@ -233,6 +463,14 @@ # my ($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdst) = localtime($cl->{time}); + $Stat{FirstCommand} = $cl->{time} unless $Stat{FirstCommand}; + $Stat{LastCommand} = 0 unless defined $Stat{LastCommand}; + $Stat{TotalTime} += $cl->{time} - $Stat{LastCommand} + if $cl->{time} - $Stat{LastCommand} < $Config{stat_inactivity_interval}; + $Stat{LastCommand} = $cl->{time}; + $Stat{TotalCommands} = 0 unless $Stat{TotalCommands}; + $Stat{TotalCommands}++; + # Добавляем спереди 0 для удобочитаемости $min = "0".$min if $min =~ /^.$/; $hour = "0".$hour if $hour =~ /^.$/; @@ -241,6 +479,8 @@ $class=$cl->{"out_class"}; $class =~ s/output$//; + $Stat{ErrorCommands}++ + if $class =~ /wrong/; $Result{"body"} .= "\n"; @@ -249,7 +489,7 @@ if ( $last_day ne $day) { #$Result{"body"} .= ""; $Result{"body"} .= ""; - $toc .= "
  • ".$Day_Name[$wday]."
  • \n"; + push @toc, "".$Day_Name[$wday]."\n"; $last_day=$day; } @@ -271,9 +511,12 @@ # COMMAND $Result{"body"} .= "
    "; + $Result{"body"} .= "

    ".$cl->{note_title}."

    " if $cl->{note_title}; + $Result{"body"} .= "".$note."

    День ",$day,"

    ".$Day_Name[$wday]."

    \n"; $Result{"body"} .= "
    \n";
    -		my $cline = $cl->{"cline"};
    +		my $cline = $cl->{"prompt"}.$cl->{"cline"};
     		$cline =~ s/\n//;
    -		$Result{"body"} .= $cl->{"prompt"}.$cl->{"cline"};
    +		my $hint = make_comment($cl->{"cline"});
    +	#	join(" ",@new_commands), join (" ",@new_files));
    +		$cline = "
    $cline
    " if $hint; + $Result{"body"} .= $cline; $Result{"body"} .= "
    \n"; my $last_command = $cl->{"last_command"}; @@ -294,10 +537,22 @@ $Result{"body"} .= $cl->{"diff"}; $Result{"body"} .= "
    "; } + + #NOTES + if ( $Config{"show_notes"} =~ /^y/i && $cl->{"note"}) { + my $note=$cl->{"note"}; + $note =~ s/\n/\n/msg; + # Ширину пока не используем + # $Result{"body"} .= ""; + $Result{"body"} .= "
    "; + $Result{"body"} .= "" if $cl->{note_title}; + $Result{"body"} .= ""; + $Result{"body"} .= "
    ".$cl->{note_title}."
    ".$note."
    \n"; + } # COMMENT if ( $Config{"show_comments"} =~ /^y/i) { - my $comment = make_comment(join(" ",@new_commands), join (" ",@new_files)); + my $comment = make_comment($cl->{"cline"}); if ($comment) { $Result{"body"} .= "". "
    "; @@ -315,18 +570,100 @@ $Result{"body"} .= "
    \n"; - $Result{"stat"} = "
    "; + #$Result{"stat"} = "
    "; + + %StatNames = ( + FirstCommand => "Время первой команды журнала", + LastCommand => "Время последней команды журнала", + TotalCommands => "Количество командных строк в журнале", + ErrorsPercentage => "Процент команд с кодом ненулевым кодом завершения, %", + TotalTime => "Суммарное время работы с терминалом *, час", + CommandsPerTime => "Количество командных строк в единицу времени, команда/мин", + CommandsFDistribution => "Частота использования команд", + CommandsFDistribution => "Частота использования команд", + RareCommands => "Частота использования этих команд < 0.5%", + ); + @StatOrder = ( + FirstCommand, + LastCommand, + TotalCommands, + ErrorsPercentage, + TotalTime, + CommandsPerTime, + CommandsFDistribution, + RareCommands, + ); + + # Подготовка статистики к выводу + # Некоторые значения пересчитываются! + # Дальше их лучше уже не использовать!!! + + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($Stat{FirstCommand}); + $Stat{FirstCommand} = sprintf "%02i:%02i:%02i %04i-%2i-%2i", $hour, $min, $sec, $year+1900, $mon+1, $mday; + ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($Stat{LastCommand}); + $Stat{LastCommand} = sprintf "%02i:%02i:%02i %04i-%2i-%2i", $hour, $min, $sec, $year+1900, $mon+1, $mday; + $Stat{ErrorsPercentage} = sprintf "%5.2f", $Stat{ErrorCommands}*100/$Stat{TotalCommands} + if $Stat{TotalCommands}; + $Stat{CommandsPerTime} = sprintf "%5.2f", $Stat{TotalCommands}*60/$Stat{TotalTime} + if $Stat{TotalTime}; + $Stat{TotalTime} = sprintf "%5.2f", $Stat{TotalTime}/60/24; + + my $total_commands=0; + for $command (keys %CommandsFDistribution){ + $total_commands += $CommandsFDistribution{$command}; + } + if ($total_commands) { + for $command (reverse sort {$CommandsFDistribution{$a} <=> $CommandsFDistribution{$b}} keys %CommandsFDistribution){ + my $percentage = sprintf "%5.2f",$CommandsFDistribution{$command}*100/$total_commands; + if ($percentage < 0.5) { + my $hint = make_comment($command); + my $command_html = "$command"; + $command_html = "$command_html" if $hint; + my $command_html = "$command_html"; + $Stat{RareCommands} .= $command_html."".$CommandsFDistribution{$command}." , "; + } + else { + my $hint = make_comment($command); + my $command_html = "$command"; + $command_html = "$command_html" if $hint; + my $command_html = "$command_html"; + $percentage = sprintf "%5.2f",$percentage; + $Stat{CommandsFDistribution} .= "".$command_html."".$CommandsFDistribution{$command}."". + "|".("="x int($CommandsFDistribution{$command}*100/$total_commands))."| $percentage%"; + } + } + $Stat{CommandsFDistribution} = "".$Stat{CommandsFDistribution}."
    "; + $Stat{RareCommands} =~ s/, $//; + } + $Result{"stat"} .= "

    Статистика

    "; - $Result{"stat"} .= "Статистическая информация о журнале
    "; - $Result{"help"} .= "
    "; + $Result{"stat"} .= ""; + for my $stat (@StatOrder) { + $Result{"stat"} .= ""; + } + + $Result{"stat"} .= "
    ".$StatNames{"$stat"}."".$Stat{"$stat"}."
    "; + $Result{"stat"} .= "____
    *) Интервалы неактивности длительностью ".($Config{stat_inactivity_interval}/60)." минут и более не учитываются

    "; + + #$Result{"help"} .= "
    "; $Result{"help"} .= "

    Справка

    "; $Result{"help"} .= "$Html_Help
    "; - $Result{"about"} .= "
    "; + #$Result{"about"} .= "
    "; $Result{"about"} .= "

    О программе

    "; $Result{"about"} .= "$Html_About"; $Result{"footer"} .= "\n"; $Result{"footer"} .= "\n"; + $Result{"title"} = "Журнал лабораторных работ"; + $Result{"title"}.= " -- ".$course_student if $course_student; + if ($course_date) { + $Result{"title"}.= " -- ".$course_date; + $Result{"title"}.= "/".$course_code if $course_code; + } + else { + $Result{"title"}.= " -- ".$course_code if $course_code; + } + # Заголовок генерируется позже всего # Тогда, когда известно уже, что должно быть написано в # оглавлении @@ -335,21 +672,27 @@ + $Result{title} -

    Журнал лабораторных работ

    +

    Журнал лабораторных работ

    -

    - Выполнил $course_student
    - Проверил $course_trainer
    - Курс $course_name ($course_code), - $course_date
    - Учебный центр $course_center
    -

    +HEADER + $Result{"header"} .= "

    " if $course_student || $course_trainer || $course_name || $course_code || $course_date || $course_center; + $Result{"header"} .= "Выполнил $course_student
    " if $course_student; + $Result{"header"} .= "Проверил $course_trainer
    " if $course_trainer; + $Result{"header"} .= "Курс " if $course_name || $course_code || $course_date; + $Result{"header"} .= "$course_name " if $course_name; + $Result{"header"} .= "($course_code)" if $course_code; + $Result{"header"} .= ", $course_date
    " if $course_date; + $Result{"header"} .= "Учебный центр $course_center
    " if $course_center; + $Result{"header"} .= "

    " if $course_student || $course_trainer || $course_name || $course_code || $course_date || $course_center; + my $toc = collapse_list (\@toc); + $Result{"header"} .= <
  • Журнал
    • $toc
    @@ -360,7 +703,7 @@

    Журнал

    HEADER - $Result{"header"} .= "
    \n"; + $Result{"header"} .= "
    \n"; for my $element (keys %Elements_Visibility) { my @e = split /\s+/, $element; @@ -385,13 +728,205 @@ +sub collapse_list($) +{ + my $res = ""; + for my $elem (@{$_[0]}) { + if (ref $elem eq "ARRAY") { + $res .= "
      ".collapse_list($elem)."
    "; + } + else + { + $res .= "
  • ".$elem."
  • "; + } + } + return $res; +} + sub init_variables { $Html_Help = < +
  • + В журнал автоматически попадают все команды, данные в любом терминале системы. +

  • +
  • + Для того чтобы убедиться, что журнал на текущем терминале ведётся, + и команды записываются, дайте команду w. + В поле WHAT, соответствующем текущему терминалу, + должна быть указана программа script. +

  • +
  • + Команды, код завершения которых отличен от нуля, выделяются цветом. + Если код завершения команды равен нулю, + команда была выполнена без ошибок. + + + + +
    +
    +\$ l s-l
    +
    bash: l: command not found
    +
    +
    +
    +

  • +
  • + Команды, ход выполнения которых был прерван пользователем, выделяются цветом. + + + + +
    +
    +\$ 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
    +
    2a3,5
    +> 	if [ -f /usr/local/etc/bash_completion ]; then
    +>         . /usr/local/etc/bash_completion
    +>     	fi
    +
    +
    +

  • +
  • + Для того чтобы получить краткую справочную информацию о команде, + нужно подвести к ней мышь. Во всплывающей подсказке появится краткое + описание команды. +

  • +
  • + Время ввода команды, показанное в журнале, соответствует времени + начала ввода командной строки, которое равно тому моменту, + когда на терминале появилось приглашение интерпретатора +

  • +
  • + Имя терминала, на котором была введена команда, показано в специальном блоке. + Этот блок показывается только в том случае, если терминал + текущей команды отличается от терминала предыдущей. +

  • +
  • + Вывод не интересующих вас в настоящий момент элементов журнала, + таких как время, имя терминала и других, можно отключить. + Для этого нужно воспользоваться формой управления журналом + вверху страницы. +

  • +
  • + Небольшие комментарии к командам можно вставлять прямо из командной строки. + Комментарий вводится прямо в командную строку, после символов #^ или #v. + Символы ^ и v показывают направление выбора команды, к которой относится комментарий: + ^ - к предыдущей, v - к следующей. + Например, если в командной строке было введено: +

    +\$ whoami
    +
    +
    +user
    +
    +
    +\$ #^ Интересно, кто я?
    +
    + в журнале это будет выглядеть так: + +
    +\$ whoami
    +
    +
    +user
    +
    +
    +
    Интересно, кто я?
    +

  • +
  • + Если комментарий содержит несколько строк, + его можно вставить в журнал следующим образом: +

    +\$ whoami
    +
    +
    +user
    +
    +
    +\$ cat > /dev/null #^ Интересно, кто я?
    +
    +
    +Программа whoami выводит имя пользователя, под которым 
    +мы зарегистрировались в системе.
    +-
    +Она не может ответить на вопрос о нашем назначении 
    +в этом мире.
    +
    + В журнале это будет выглядеть так: + + + + +
    +
    +\$ whoami
    +
    user
    +
    +
    Интересно, кто я?
    +Программа whoami выводит имя пользователя, под которым
    +мы зарегистрировались в системе.
    +
    +Она не может ответить на вопрос о нашем назначении
    +в этом мире.
    +
    +
    + Для разделения нескольких абзацев между собой + используйте символ "-", один в строке. +
    +

  • +
  • + Комментарии, не относящиеся непосредственно ни к какой из команд, + добавляются точно таким же способом, только вместо симолов #^ или #v + нужно использовать символы #= +

  • + HELP $Html_About = < "yes", "suppress_terminal" => "yes", - "terminal_width" => 100, + "terminal_width" => 400, "terminal_height" => 100, "verbose" => "yes", "head_lines" => 5, "tail_lines" => 5, - "cache_head_lines" => 5, - "cache_tail_lines" => 5, + "cache_head_lines" => 50, + "cache_tail_lines" => 50, "skip_text" => "...", "show_time" => "yes", "show_diffs" => "yes", "show_comments" => "yes", + "show_notes" => "yes", "input" => "/root/.labmaker", "diffs" => "", @@ -54,6 +55,11 @@ "frontend_opennet_ico" => "/l3/opennet.ico", "frontend_local_ico" => "/l3/freebsd.ico", + "mywi_server" => "127.0.0.1", + "mywi_port" => "19800", + + "stat_inactivity_interval" => "1800", + "signature" => "#lm:", "from" => "", "to" => "", @@ -62,6 +68,7 @@ "files_keywords" => "linux file", comment_width => "300", + note_width => "500", time_width => "60", "mode" => "daemon", # daemon | normal