21、脚本编程实用案例:加密、文件传输与新闻监控

脚本编程实用案例:加密、文件传输与新闻监控

1. 目录加密脚本

在UNIX系统中, crypt 命令可对单个文件进行加密,但如果要同时加密多个文件,手动操作会很繁琐。下面的 cryptdir 脚本可以对指定目录下的所有文件进行加密或解密。

1.1 脚本功能概述

  • 加密或解密 :根据脚本名称( cryptdir decryptdir )决定是加密还是解密操作。
  • 密码验证 :加密时要求输入两次密码,避免因输入错误而导致文件加密失败。
  • 避免重复加密 :使用 .crypt 后缀来标识已加密文件,避免对已加密文件再次加密。

1.2 脚本代码

#!/usr/local/bin/expect --
# encrypt/decrypt an entire directory 
# optional arg is dirname, else cwd 
if {[llength $argv] > 0} { 
    cd $argv 
}
# encrypt or decrypt? 
set decrypt [regexp "decrypt" $argv0] 

set timeout -1 
stty -echo 
send "Password:" 
expect -re "(.*)\n" 
send "\n" 
set passwd $expect_out(1,string) 

# wouldn't want to encrypt files with mistyped password! 
if ! $decrypt { 
    send "Again:" 
    expect -re "(.*) \n" 
    send "\n" 
    if ! [string match $passwd $expect_out(1,string)] {
        send_user "mistyped password?" 
        stty echo 
        exit 
    }
}
stty echo 

log_user 0 
foreach f [glob *] { 
    set strcmp [string compare .crypt [file extension $f]] 
    if $decrypt { 
        # skip files that don't end with ".crypt" 
        if 0!=$strcmp continue 
        spawn sh -c "exec crypt < $f > [file root $f]" 
    } else { 
        # skip files that already end with ".crypt" 
        if 0==$strcmp continue 
        spawn sh -c "exec crypt < $f > $f.crypt" 
        expect "key:" 
        send "$passwd\r" 
        expect 
        wait 
        exec rm -f $f 
    }
}

1.3 操作步骤

  1. 保存脚本 :将上述代码保存为 cryptdir decryptdir
  2. 赋予执行权限 chmod +x cryptdir decryptdir
  3. 执行脚本
    • 加密当前目录: ./cryptdir
    • 加密指定目录: ./cryptdir /path/to/directory
    • 解密当前目录: ./decryptdir
    • 解密指定目录: ./decryptdir /path/to/directory

2. 通过 Telnet 进行文件传输

传统的 ftp 程序在某些复杂网络环境下无法正常工作,下面的脚本可以在多种链接上进行文件传输,且不需要在远程端有副本。

2.1 脚本功能概述

  • 交互式操作 :提示用户输入文件名和其他命令。
  • 压缩和编码 :使用 compress uuencode 对文件进行压缩和编码,提高传输速度并解决二进制文件传输问题。
  • 避免冲突 :使用进程 ID 来避免多个用户之间的冲突。

2.2 脚本代码

#!/usr/local/bin/expect --
if [info exists env(EXPECT_PROMPT)] {
    set prompt $env(EXPECT_PROMPT) 
} else { 
    set prompt "(%1#1\\$) $" ;# default prompt 
}
set timeout -1 
set verbose_flag 0 

spawn -noecho $env(SHELL) 
send_user "Once logged in, cd to directory to transfer\ 
to/from and press: --\n" 
send_user "One moment ... \n" 
interact -- cmd 

proc cmd {} { 
    set CTRLZ \032 
    send_user "command (g,p,? for more): " 
    expect_user { 
        g get_main 
        p put_main 
        c chdir 
        v verbose 
        - {send "-"} 
        "\\?" { 
            send_user "?\n" 
            send_user "--g get file from remote system\n" 
            send_user "--p put file to remote system\n" 
            send_user "--c change/show directory on local system\n" 
            send_user "-- - send - to remote system\n" 
            send_user "--? this list\n" 
            send_user "--v verbose mode toggle\ 
(currently [verbose_status])\n" 
            send_user "--$CTRLZ suspend\n" 
        }
        $CTRLZ { 
            stty -raw echo 
            exec kill -STOP [pid] 
            stty raw -echo 
        }
        -re . {send_user "unknown command\n"} 
        send_user "resuming session ... \n" 
    }
}

proc verbose {} { 
    global verbose_flag 
    set verbose_flag [expr !$verbose_flag] 
    send_user "verbose [verbose_status]\r\n" 
}

proc verbose_status {} { 
    global verbose_flag 
    if $verbose_flag {
        return "on" 
    } else { 
        return "off" 
    }
}

proc send_verbose {msg} {
    global verbose_flag 
    if $verbose_flag { 
        send_user $msg 
    }
}

proc chdir {} { 
    stty -raw echo 
    send_user "c\n" 
    send_user "current directory: [pwd], new directory: " 
    expect_user -re "(.*) \n" { 
        cd $expect_out(1,string) 
        stty raw -echo 
    }
}

proc get_main {} { 
    stty -raw echo 
    send_user "g\nget remote file \ [localfile] : " 
    expect_user { 
        -re "([A-Za-z0-9_.-]+) +([A-Za-z0-9_.-]+)\n" { 
            send_user "copying (remote) $expect_out(1,string) to\ 
(local) $expect_out(2,string)\n" 
            get $expect_out(1,string) $expect_out(2,string) 
        }
        -re "([A-Za-z0-9_.-]+)\n" { 
            send_user "copying $expect_out(1,string)\n" 
            get $expect_out(1,string) $expect_out(1,string) 
        }
        -re "\n" { 
            send_user "eh?\n" 
            stty raw -echo 
        }
    }
}

proc put_main {} { 
    stty -raw echo 
    send_user "p\nput local file \ [remotefile] : " 
    expect_user { 
        -re "([A-Za-z0-9_.-]+) +([A-Za-z0-9_.-]+)\n" { 
            send_user "copying (local) $expect_out(1,string) to\ 
(remote) $expect_out(2,string)\n" 
            put $expect_out(1,string) $expect_out(2,string) 
        }
        -re "([A-Za-z0-9_.-]+)\n" { 
            send_user "copying $expect_out(1,string)\n" 
            put $expect_out(1,string) $expect_out(1,string) 
        }
        -re "\n" { 
            send_user "eh?\n" 
            stty raw -echo 
        }
    }
}

proc get {infile outfile} {
    global prompt verbose_flag 
    if (!$verbose_flag) {
        log_user 0 
    }
    send_verbose "disabling echo: " 
    send "stty -echo\r" 
    expect -re $prompt 
    send_verbose "remote pid is " 
    send "echo $$\r" 
    expect -re "(.*)\r\n.*$prompt" 
    set rpid $expect_out(1,string) 
    set pid [pid] 
    # pid is local pid, rpid is remote pid 
    set infile_main "/tmp/$rpid" 
    set infile_compressed "$infile_main.Z" 
    set infile_encoded "$infile_compressed.uu" 
    set outfile_main "/tmp/$pid" 
    set outfile_compressed "$outfile_main.Z" 
    set outfile_encoded "$outfile_compressed.uu" 
    set out [open $outfile_encoded w] 
    send_verbose "compressing\n" 
    send "compress -fc $infile > $infile_compressed\r" 
    expect -re $prompt 
    send_verbose "uuencoding\n" 
    send "uuencode $infile_compressed $outfile_compressed > \ 
$infile_encoded\r" 
    expect -re $prompt 
    send_verbose "copying\n" 
    send "cat $infile_encoded\r" 
    expect { 
        -re "end\r\n" { 
            puts $out "end" 
            close $out 
        }
        -re "([^\r]*)\r\n" { 
            puts $out $expect_out(1,string) 
            send_verbose 
            exp_continue 
        }
    }
    if ($verbose_flag) {
        send_user "\n" 
    }
    log_user 1 
    expect -re $prompt ;# wait for prompt from cat 
    send_verbose "deleting temporary files\n" 
    send "rm -f $infile_compressed $infile_encoded\r" 
    expect -re $prompt 
    send_verbose "switching attention to local system\n\ 
uudecoding\n" 
    exec uudecode $outfile_encoded 
    send_verbose "uncompressing\n" 
    exec uncompress -f $outfile_compressed 
    send_verbose "renaming\n" 
    if [catch "exec cp $outfile_main $outfile" msg] { 
        send_user "could not move file in place, reason: $msg\n" 
        send_user "left as $outfile_main\n" 
        exec rm -f $outfile_encoded 
    } else { 
        exec rm -f $outfile_main $outfile_encoded 
    }
    # restore echo and serendipitously reprompt 
    send "stty echo\r" 
}

proc put {infile outfile} {
    global prompt verbose_flag 
    if (!$verbose_flag) {
        log_user 0 
    }
    send_verbose "disabling echo: " 
    send "stty -echo\r" 
    expect -re $prompt 
    send_verbose "remote pid is " 
    send "echo $$\r" 
    expect -re "(.*)\r\n.*$prompt" 
    set rpid $expect_out(1,string) 
    set pid [pid] 
    # pid is local pid, rpid is remote pid 
    set infile_main "/tmp/$pid" 
    set infile_compressed "$infile_main.Z" 
    set infile_encoded "$infile_compressed.uu" 
    set outfile_main "/tmp/$rpid" 
    set outfile_compressed "$outfile_main.z" 
    set outfile_encoded "$outfile_compressed.uu" 
    set out [open $outfile_encoded w] 
    send_verbose "compressing\n" 
    exec compress -fc $infile > $infile_compressed 
    send_verbose "uuencoding\n" 
    exec uuencode $infile_compressed $outfile_compressed > \ 
$infile_encoded 
    send_verbose "copying\n" 
    send "cat > $outfile_encoded\r" 
    set fp [open $infile_encoded r] 
    while 1 { 
        if {-1 == [gets $fp buf]} break 
        send_verbose "." 
        send "$buf\r" 
        if ($verbose_flag) {
            send_user "\n" 
        }
    }
    log_user 1 
    send "\004" 
    close $fp ;# eof 
    send_verbose "deleting temporary files\n" 
    exec rm -f $infile_compressed $infile_encoded 
    send_verbose "switching attention to remote system\n" 
    expect -re $prompt ;# wait for prompt from cat 
    send_verbose "uudecoding\n" 
    send "uudecode $outfile_encoded\r" 
    expect -re $prompt 
    send_verbose "uncompressing\n" 
    send "uncompress -f $outfile_compressed\r" 
    expect -re $prompt 
    send_verbose "renaming\n" 
    send "cp $outfile_main $outfile\r" 
    expect -re $prompt 
    send_verbose "deleting temporary files\n" 
    send "rm -f $outfile_main $outfile_encoded\r" 
    expect -re $prompt 
    # restore echo and serendipitously reprompt 
    send "stty echo\r" 
}

2.3 操作步骤

  1. 保存脚本 :将上述代码保存为一个文件,例如 file_transfer
  2. 赋予执行权限 chmod +x file_transfer
  3. 执行脚本 ./file_transfer
  4. 连接远程系统 :使用 telnet tip 等外部程序连接到远程系统。
  5. 进入远程目录 :在远程系统中进入要进行文件传输的目录。
  6. 执行命令 :输入 -- 调用 cmd 过程,根据提示输入相应命令进行文件传输。

3. 未读新闻监控脚本 tknewsbiff

tknewsbiff 脚本可以监控 Usenet 新闻,当有未读新闻时,会播放音频或执行其他操作。

3.1 脚本功能概述

  • 可定制性 :用户可以通过添加额外的 Tcl 命令来自定义脚本行为。
  • 新闻监控 :定期检查新闻服务器,显示有未读新闻的新闻组和未读文章数量。
  • 用户交互 :提供简单的鼠标绑定,方便用户操作。

3.2 脚本代码

#!/usr/local/bin/expectk 
proc unmapwindow {} { 
    global _window_open 
    switch [wm state .] {
        iconic { 
            set _window_open 0 
        }
        normal { 
            set _window_open 1 
        }
    }
    wm withdraw . 
}

unmapwindow 
# force window to be open when mapped for the first time 
set _window_open 1 

proc mapwindow {} { 
    global _window_open 
    if $_window_open { 
        wm deiconify . 
    } else { 
        wm iconify . 
    }
}

proc _abort {msg} {
    global argv0 
    puts "$argv0: $msg" 
    exit 1 
}

if [info exists env(DOTDIR)] {
    set home $env(DOTDIR) 
} else {
    set home [glob -] 
}
set delay 60 
set width 27 
set height 10 
set _default_config_file $home/.tknewsbiff 
set _config_file $_default_config_file 
set default_server "news" 
set server $_default_server 
set server_timeout 60 

log_user 0 

listbox .list -yscroll ".scrollbar set" -font "*-m-*" -setgrid 1 
scrollbar .scrollbar -command ".list yview" -relief raised 
pack .scrollbar -side left -fill y 
pack .list -side left -fill both -expand 1 

while {[llength $argv]>0} { 
    set arg [lindex $argv 0] 
    if [file readable $arg] { 
        if 0== [string compare "active" [file tail $arg]] { 
            set active_file $arg 
            set argv [lrange $argv 1 end] 
        } else { 
            # must be a config file 
            set _config_file $arg 
            set argv [lrange $argv 1 end] 
        }
    } elseif {[file readable $_config_file-$arg]} {
        # maybe it's a hostname suffix for a newsrc file? 
        set _config_file $_default_config_file-$arg 
        set argv [lrange $argv 1 end] 
    } else { 
        # maybe just a hostname for a regular newsrc file? 
        set server $arg 
        set argv [lrange $argv 1 end] 
    }
}

proc _read_config_file {} { 
    global _config_file argv0 watch_list ignore_list 
    proc user {} {} 
    set watch_list {} 
    set ignore_list {} 
    if [file exists $_config_file] {
        # uplevel allows user to set global variables 
        if [catch {uplevel source $_config_file} msg] {
            _abort "error reading $_config_file\n$msg" 
        }
    }
    if [llength $watch_list]==0 { 
        watch * 
    }
}

proc watch {args} { 
    global watch_list 
    lappend watch_list $args 
}

proc ignore {ng} { 
    global ignore_list 
    lappend ignore_list $ng 
}

_read_config_file 

# if user didn't set newsrc, try -/.newsrc-server 
# if that fails, fall back to just plain -/.newsrc 
if ![info exists newsrc] { 
    set newsrc $home/.newsrc-$server 
    if ![file readable $newsrc] { 
        set newsrc $home/.newsrc 
        if ![file readable $newsrc] {
            _abort "cannot tell what newgroups you read - found\ 
neither $home/.newsrc-$server nor $home/.newsrc" 
        }
    }
}
# initialize display 
set min_reasonable_width 8 
wm minsize . $min_reasonable_width 1 
wm maxsize . 999 999 
if {0 == [info exists active_file] && 
    0 != [string compare $server $_default_server]} {
    wm title . "news@$server" 
    wm iconname . "news@$server" 
}

proc _read_newsrc {} {
    global db newsrc 
    if [catch {set file [open $newsrc]} msg] { 
        _abort $msg 
    }
    while {-1 != [gets $file buf]} { 
        if [regexp "!" $buf] continue 
        if [regexp "([^:]*):.*[-, ] ([0-9]+)" $buf dummy ng seen] {
            set db($ng, seen) $seen 
        }
    }
    close $file 
}

proc _read_active {} {
    global db server active_list active_file 
    upvar #0 server_timeout timeout 
    set active_list {} 
    if [info exists active_file] { 
        spawn -open [open $active_file] 
    } else { 
        spawn telnet $server nntp 
        expect { 
            "20*\n" { 
                # should get 200 or 201 
            }
            "NNTP server*\n" { 
                puts "tknewsbiff: unexpected response from server:" 
                puts "$expect_out(buffer) " 
                return 1 
            }
            "unknown host" {
                _unknown_host 
            }
            timeout {
                close 
                wait 
                return 1 
            }
            eof { 
                # loadav too high probably 
                wait 
                return 1 
            }
        }
        exp_send "list\r" 
        # ignore echo of "list" command 
        expect "list\r\n" 
        # skip "Newsgroups in form" line 
        expect -re "215\[^\n]*\n" 
        expect -re "([^ ]*) 0*([^ ]+) [^\n]*\n" { 
            set ng $expect_out(1,string) 
            set hi $expect_out(2,string) 
            lappend active_list $ng 
            set db($ng,hi) $hi 
            exp_continue 
        }
        " . \r\n" {
            close 
            wait 
            return 0 
        }
    }
}

proc _unknown_host {} {
    global server _default_server 
    if 0==[string compare $_default_server $server] { 
        puts "tknewsbiff: default server <$server> is not known" 
    } else { 
        puts "tknewsbiff: server <$server> is not known" 
    }
    puts "Give tknewsbiff an argument - either the name\ 
of your news server or active file. 
I.e., 
tknewsbiff news.nist.gov 
tknewsbiff /usr/news/lib/active 
\n\ 
If you have a correctly defined configuration file\ 
(.tknewsbiff), an argument is not required. 
See the\ 
man page for more info." 
    exit 1 
}

proc _update_ngs {} {
    global watch_list active_list newsgroup 
    foreach watch $watch_list {
        set threshold 1 
        set display "display" 
        set new {} 
        set ngpat [lindex $watch 0] 
        set watch [lrange $watch 1 end] 
        while {[llength $watch] > 0} { 
            switch -- [lindex $watch 0] {
                -threshold { 
                    set threshold [lindex $watch 1] 
                    set watch [lrange $watch 2 end] 
                }
                -display { 
                    set display [lindex $watch 1] 
                    set watch [lrange $watch 2 end] 
                }
                -new { 
                    set new [lindex $watch 1] 
                    set watch [lrange $watch 2 end] 
                }
                default { 
                    _abort "watch: expecting -threshold, -display or\ 
-new but found: [lindex $watch 0]" 
                }
            }
        }
        foreach ng $active_list { 
            if [string match $ngpat $ng] { 
                if [_isgood $ng $threshold] {
                    if [llength $display] { 
                        set newsgroup $ng 
                        uplevel $display 
                    }
                    if [_isnew $ng] { 
                        if [llength $new] {
                            set newsgroup $ng 
                            uplevel $new 
                        }
                    }
                }
            }
        }
    }
}

proc _isgood {ng threshold} {
    global db seen_list ignore_list 
    # skip if we don't subscribe to it 
    if ! [info exists db($ng,seen)] {return 0} 
    # skip if the threshold isn't exceeded 
    if {$db($ng,hi) - $db($ng,seen) < $threshold} {
        return 0 
    }
    # skip if it matches an ignore command 
    foreach igpat $ignore_list { 
        if [string match $igpat $ng] {return 0} 
    }
    # skip if we've seen it before 
    if [lsearch -exact $seen_list $ng] !=-1 {return 0} 
    # passed all tests, so remember that we've seen it 
    lappend seen_list $ng 
    return 1 
}

proc _isnew {ng} {
    global previous_seen_list 
    if [lsearch -exact $previous_seen_list $ng]==-1 { 
        return 1 
    } else { 
        return 0 
    }
}

proc display {} {
    global display_list newsgroup 
    lappend display_list $newsgroup 
}

proc _update_window {} {
    global server display_list height width 
    global min_reasonable_width 
    if {0 == [llength $display_list]} {
        unmapwindow 
        return 
    }
    # make height correspond to length of display_list or 
    # user's requested max height, whichever is smaller 
    if {[llength $display_list] < $height} { 
        set current_height [llength $display_list] 
    } else { 
        set current_height $height 
    }
    # force reasonable min width 
    if {$width < $min_reasonable_width} {
        set width $min_reasonable_width 
    }
    wm geometry . "${width}x$current_height" 
    wm maxsize . 999 [llength $display_list] 
    if [string compare [wm state .] "withdrawn"]==0 { 
        mapwindow 
    }
    _display_ngs $width 
}

proc _display_ngs {width} {
    global db display_list 
    set str_width [expr $width-7] 
    .list delete 0 end 
    foreach ng $display_list {
        .list insert end [ 
            format "%-$str_width.${str_width}s %5d" \ 
            $ng [expr $db($ng,hi) - $db($ng,seen)] 
        ]
    }
}

bind .list <1> help 
bind .list <2> update-now 
bind .list <3> unmapwindow 
bind .list <Configure> { 
    scan [wm geometry .] "%dx%d" w h 
    _display_ngs $w 
}

spawn cat -u; set _cat_spawn_id $spawn_id 
set _update_flag 0 

proc _sleep {timeout} {
    global _cat_spawn_id _update_flag 
    # restore to idle cursor 
   .list config -cursor ""; update 
    # sleep for a little while, subject to click from 
    # "update" button 
    expect -i $_cat_spawn_id -re "....";# two crlfs 
    # change to busy cursor 
   .list config -cursor watch; update 
}

proc update-now {} {
    global _update_flag _cat_spawn_id 
    if $_update_flag return 
    set _update_flag 1 
}

set previous_seen_list {} 
set seen_list {} 

proc _init_ngs {} {
    global display_list db 
    global seen_list previous_seen_list 
    set display_list {} 
    set seen_list {} 
    catch {unset db} 
}

for {} 1 {_sleep $delay} { 
    _init_ngs 
    _read_newsrc 
    if [_read_active] continue 
    _read_config_file 
    _update_ngs 
    user 
    _update_window 
}

2.4 操作步骤

  1. 保存脚本 :将上述代码保存为 tknewsbiff
  2. 赋予执行权限 chmod +x tknewsbiff
  3. 创建配置文件 :在用户主目录下创建 .tknewsbiff 文件,添加自定义配置,例如:
set server news.nist.gov 
set delay 120 
set server_timeout 60 
set height 10 
watch comp.unix.* 
watch *.sources.* 
watch dc.dining 
ignore *.d 
  1. 执行脚本 ./tknewsbiff

2.5 鼠标绑定说明

鼠标按键 功能
左键 弹出帮助窗口
中键 立即检查新的未读新闻
右键 隐藏窗口直到下一个更新周期
窗口调整大小 重新绘制窗口

2.6 mermaid 流程图

graph TD;
    A[开始] --> B[初始化窗口和变量];
    B --> C[读取配置文件];
    C --> D[读取 newsrc 文件];
    D --> E[检查新闻组文章数量];
    E --> F[更新新闻组信息];
    F --> G[执行用户自定义操作];
    G --> H[更新窗口显示];
    H --> I[休眠];
    I --> D;

以上就是三个实用脚本的详细介绍和操作步骤,希望能帮助你更好地完成目录加密、文件传输和新闻监控等任务。

4. 脚本技术细节分析

4.1 目录加密脚本技术点

  • 密码验证 :在加密过程中,为避免因输入错误的密码而导致文件加密失败,脚本要求用户输入两次密码,并使用 string match 函数进行比较。若两次输入不一致,脚本将提示错误并退出。
if ! $decrypt { 
    send "Again:" 
    expect -re "(.*) \n" 
    send "\n" 
    if ! [string match $passwd $expect_out(1,string)] {
        send_user "mistyped password?" 
        stty echo 
        exit 
    }
}
  • 避免重复加密 :脚本使用 .crypt 后缀来标识已加密文件。在遍历文件列表时,通过 string compare 函数比较文件扩展名,跳过已加密或无需解密的文件。
foreach f [glob *] { 
    set strcmp [string compare .crypt [file extension $f]] 
    if $decrypt { 
        # skip files that don't end with ".crypt" 
        if 0!=$strcmp continue 
        spawn sh -c "exec crypt < $f > [file root $f]" 
    } else { 
        # skip files that already end with ".crypt" 
        if 0==$strcmp continue 
        spawn sh -c "exec crypt < $f > $f.crypt" 
        expect "key:" 
        send "$passwd\r" 
        expect 
        wait 
        exec rm -f $f 
    }
}

4.2 文件传输脚本技术点

  • 压缩和编码 :为提高传输速度和解决二进制文件传输问题,脚本使用 compress uuencode 对文件进行压缩和编码。在 get put 过程中,分别对文件进行相应处理。
# get 过程中的压缩和编码
send_verbose "compressing\n" 
send "compress -fc $infile > $infile_compressed\r" 
expect -re $prompt 
send_verbose "uuencoding\n" 
send "uuencode $infile_compressed $outfile_compressed > \ 
$infile_encoded\r" 
expect -re $prompt 

# put 过程中的压缩和编码
send_verbose "compressing\n" 
exec compress -fc $infile > $infile_compressed 
send_verbose "uuencoding\n" 
exec uuencode $infile_compressed $outfile_compressed > \ 
$infile_encoded 
  • 避免冲突 :使用进程 ID( pid )来避免多个用户之间的冲突。在本地和远程系统中,分别使用不同的进程 ID 来命名临时文件。
set pid [pid] 
# pid is local pid, rpid is remote pid 
set infile_main "/tmp/$rpid" 
set infile_compressed "$infile_main.Z" 
set infile_encoded "$infile_compressed.uu" 
set outfile_main "/tmp/$pid" 
set outfile_compressed "$outfile_main.Z" 
set outfile_encoded "$outfile_compressed.uu" 

4.3 tknewsbiff 脚本技术点

  • 可定制性 :用户可以通过在配置文件中添加额外的 Tcl 命令来自定义脚本行为。脚本使用 uplevel source 函数来执行配置文件中的代码,允许用户设置全局变量和调用其他过程。
proc _read_config_file {} { 
    global _config_file argv0 watch_list ignore_list 
    proc user {} {} 
    set watch_list {} 
    set ignore_list {} 
    if [file exists $_config_file] {
        # uplevel allows user to set global variables 
        if [catch {uplevel source $_config_file} msg] {
            _abort "error reading $_config_file\n$msg" 
        }
    }
    if [llength $watch_list]==0 { 
        watch * 
    }
}
  • 新闻监控和更新 :脚本定期检查新闻服务器,通过 _read_newsrc _read_active 过程读取用户的新闻源文件和新闻组文章数量。然后,使用 _update_ngs 过程更新新闻组信息,并根据用户配置执行相应操作。
for {} 1 {_sleep $delay} { 
    _init_ngs 
    _read_newsrc 
    if [_read_active] continue 
    _read_config_file 
    _update_ngs 
    user 
    _update_window 
}

5. 脚本优化建议

5.1 目录加密脚本优化

  • 错误处理 :在执行 crypt 命令时,添加错误处理机制,捕获可能的错误并输出详细的错误信息。
  • 并行处理 :对于大量文件的加密或解密操作,可以考虑使用并行处理来提高效率。例如,使用 exec 命令在后台执行多个 crypt 进程。

5.2 文件传输脚本优化

  • 工具检查 :在脚本开始时,检查远程主机是否支持 rz/sz gzip 等工具,并优先使用这些工具进行文件传输。
  • 减少临时文件 :利用压缩程序可以读写管道的特性,减少临时文件的使用,避免磁盘空间的浪费。

5.3 tknewsbiff 脚本优化

  • 性能优化 :减少不必要的文件读取和网络请求,例如缓存新闻组信息,避免重复检查。
  • 用户体验优化 :添加更多的用户交互功能,如自定义声音提示、消息通知等。

6. 总结

本文介绍了三个实用脚本:目录加密脚本、文件传输脚本和未读新闻监控脚本 tknewsbiff 。这些脚本具有不同的功能和特点,通过详细的代码分析和操作步骤说明,帮助读者理解和使用这些脚本。同时,还提供了脚本的技术细节分析和优化建议,希望能为读者在实际应用中提供参考。

6.1 脚本功能总结

脚本名称 功能
目录加密脚本 对指定目录下的所有文件进行加密或解密
文件传输脚本 在多种链接上进行文件传输,支持交互式操作
tknewsbiff 脚本 监控 Usenet 新闻,当有未读新闻时执行相应操作

6.2 mermaid 流程图

graph LR;
    A[目录加密脚本] --> B[文件传输脚本];
    B --> C[tknewsbiff 脚本];
    C --> D[优化建议];
    D --> A;

通过学习和使用这些脚本,读者可以提高工作效率,实现自动化任务,同时也可以根据自己的需求对脚本进行定制和优化。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值