下边命令中的某几个命令你会在追踪垃圾邮件练习中找到其用法, 用来进行网络数据的转换和分析.
通过名字或IP地址来搜索一个互联网主机的信息, 使用DNS.
bash$ host surfacemail.com surfacemail.com. has address 202.92.42.236 |
显示一个主机IP信息.
使用-h
选项,
ipcalc将会做一个DNS的反向查询,
通过IP地址找到主机(服务器)名.
bash$ ipcalc -h 202.92.42.236 HOSTNAME=surfacemail.com |
通过IP地址在一个主机上做一个互联网的"名字服务查询". 事实上, 这与ipcalc -h或dig -x等价. 这个命令既可以交互运行也可以非交互运行, 换句话说, 就是在脚本中运行.
nslookup命令据说已经被慢慢的"忽视"了, 但事实上它是有一定的作用.
bash$ nslookup -sil 66.97.104.180 nslookup kuhleersparnis.ch Server: 135.116.137.2 Address: 135.116.137.2#53 Non-authoritative answer: Name: kuhleersparnis.ch |
Domain Information Groper(域信息查询). 与nslookup很相似, dig也可以在一个主机上做互联网的"名字服务查询". 这个命令既可以交互运行也可以非交互运行, 换句话说, 就是在脚本中运行.
下面是一些dig命令有趣的选项,
+time=N
选项用来设置查询超时为N秒,
+nofail
选项用来持续查询服务器直到收到一个响应,
-x
会做反向地址查询.
比较下边这3个命令的输出, dig -x, ipcalc -h和 nslookup.
bash$ dig -x 81.9.6.2 ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 11649 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0 ;; QUESTION SECTION: ;2.6.9.81.in-addr.arpa. IN PTR ;; AUTHORITY SECTION: 6.9.81.in-addr.arpa. 3600 IN SOA ns.eltel.net. noc.eltel.net. 2002031705 900 600 86400 3600 ;; Query time: 537 msec ;; SERVER: 135.116.137.2#53(135.116.137.2) ;; WHEN: Wed Jun 26 08:35:24 2002 ;; MSG SIZE rcvd: 91 |
例子 12-36. 查找滥用的链接来报告垃圾邮件发送者
1 #!/bin/bash 2 # spam-lookup.sh: 查找滥用的连接来报告垃圾邮件发送者. 3 # 感谢Michael Zick. 4 5 # 检查命令行参数. 6 ARGCOUNT=1 7 E_WRONGARGS=65 8 if [ $# -ne "$ARGCOUNT" ] 9 then 10 echo "Usage: `basename $0` domain-name" 11 exit $E_WRONGARGS 12 fi 13 14 15 dig +short $1.contacts.abuse.net -c in -t txt 16 # 也试试: 17 # dig +nssearch $1 18 # 尽量找到"可信赖的名字服务器"并且显示SOA记录. 19 20 # 下边这句也可以: 21 # whois -h whois.abuse.net $1 22 # ^^ ^^^^^^^^^^^^^^^ 指定主机. 23 # 使用这个命令也可以查找多个垃圾邮件发送者, 比如:" 24 # whois -h whois.abuse.net $spamdomain1 $spamdomain2 . . . 25 26 27 # 练习: 28 # ----- 29 # 扩展这个脚本的功能, 30 #+ 让它可以自动发送e-mail来通知 31 #+ 需要对此负责的ISP的联系地址. 32 # 暗示: 使用"mail"命令. 33 34 exit $? 35 36 # spam-lookup.sh chinatietong.com 37 # 一个已知的垃圾邮件域. (译者: 中国铁通 . . .) 38 39 # "crnet_mgr@chinatietong.com" 40 # "crnet_tec@chinatietong.com" 41 # "postmaster@chinatietong.com" 42 43 44 # 如果想找到这个脚本的一个更详尽的版本, 45 #+ 请访问SpamViz的主页, http://www.spamviz.net/index.html. |
例子 12-37. 分析一个垃圾邮件域
1 #! /bin/bash 2 # is-spammer.sh: 鉴别一个垃圾邮件域 3 4 # $Id: is-spammer, v 1.4 2004/09/01 19:37:52 mszick Exp $ 5 # 上边这行是RCS ID信息. 6 # 7 # 这是附件中捐献脚本is_spammer.bash 8 #+ 的一个简单版本. 9 10 # is-spammer <domain.name> 11 12 # 使用外部程序: 'dig' 13 # 测试版本: 9.2.4rc5 14 15 # 使用函数. 16 # 使用IFS来分析分配在数组中的字符串. 17 # 做一些有用的事: 检查e-mail黑名单. 18 19 # 使用来自文本体中的domain.name: 20 # http://www.good_stuff.spammer.biz/just_ignore_everything_else 21 # ^^^^^^^^^^^ 22 # 或者使用来自任意e-mail地址的domain.name: 23 # Really_Good_Offer@spammer.biz 24 # 25 # 并将其作为这个脚本的唯一参数. 26 #(另: 你的Inet连接应该保证连接好) 27 # 28 # 这样, 在上边两个实例中调用这个脚本: 29 # is-spammer.sh spammer.biz 30 31 32 # Whitespace == :Space:Tab:Line Feed:Carriage Return: 33 WSP_IFS=$'\x20'$'\x09'$'\x0A'$'\x0D' 34 35 # No Whitespace == Line Feed:Carriage Return 36 No_WSP=$'\x0A'$'\x0D' 37 38 # 域分隔符为点分10进制ip地址 39 ADR_IFS=${No_WSP}'.' 40 41 # 取得dns文本资源记录. 42 # get_txt <error_code> <list_query> 43 get_txt() { 44 45 # 分析在"."中分配的$1. 46 local -a dns 47 IFS=$ADR_IFS 48 dns=( $1 ) 49 IFS=$WSP_IFS 50 if [ "${dns[0]}" == '127' ] 51 then 52 # 查看此处是否有原因. 53 echo $(dig +short $2 -t txt) 54 fi 55 } 56 57 # 取得dns地址资源纪录. 58 # chk_adr <rev_dns> <list_server> 59 chk_adr() { 60 local reply 61 local server 62 local reason 63 64 server=${1}${2} 65 reply=$( dig +short ${server} ) 66 67 # 假设应答可能是一个错误码 . . . 68 if [ ${#reply} -gt 6 ] 69 then 70 reason=$(get_txt ${reply} ${server} ) 71 reason=${reason:-${reply}} 72 fi 73 echo ${reason:-' not blacklisted.'} 74 } 75 76 # 需要从名字中取得 IP 地址. 77 echo 'Get address of: '$1 78 ip_adr=$(dig +short $1) 79 dns_reply=${ip_adr:-' no answer '} 80 echo ' Found address: '${dns_reply} 81 82 # 一个可用的应答至少是4个数字加上3个点. 83 if [ ${#ip_adr} -gt 6 ] 84 then 85 echo 86 declare query 87 88 # 通过点中的分配进行分析. 89 declare -a dns 90 IFS=$ADR_IFS 91 dns=( ${ip_adr} ) 92 IFS=$WSP_IFS 93 94 # 用8进制表示法将dns查询循序记录起来. 95 rev_dns="${dns[3]}"'.'"${dns[2]}"'.'"${dns[1]}"'.'"${dns[0]}"'.' 96 97 # 查看: http://www.spamhaus.org (传统地址, 维护的很好) 98 echo -n 'spamhaus.org says: ' 99 echo $(chk_adr ${rev_dns} 'sbl-xbl.spamhaus.org') 100 101 # 查看: http://ordb.org (开放转发Open mail relay) 102 echo -n ' ordb.org says: ' 103 echo $(chk_adr ${rev_dns} 'relays.ordb.org') 104 105 # 查看: http://www.spamcop.net/ (你可以在这里报告spammer) 106 echo -n ' spamcop.net says: ' 107 echo $(chk_adr ${rev_dns} 'bl.spamcop.net') 108 109 # # # 其他的黑名单操作 # # # 110 111 # 查看: http://cbl.abuseat.org. 112 echo -n ' abuseat.org says: ' 113 echo $(chk_adr ${rev_dns} 'cbl.abuseat.org') 114 115 # 查看: http://dsbl.org/usage (不同的邮件转发mail relay) 116 echo 117 echo 'Distributed Server Listings' 118 echo -n ' list.dsbl.org says: ' 119 echo $(chk_adr ${rev_dns} 'list.dsbl.org') 120 121 echo -n ' multihop.dsbl.org says: ' 122 echo $(chk_adr ${rev_dns} 'multihop.dsbl.org') 123 124 echo -n 'unconfirmed.dsbl.org says: ' 125 echo $(chk_adr ${rev_dns} 'unconfirmed.dsbl.org') 126 127 else 128 echo 129 echo 'Could not use that address.' 130 fi 131 132 exit 0 133 134 # 练习: 135 # ----- 136 137 # 1) 检查脚本参数, 138 # 并且如果必要的话, 可以使用合适的错误消息退出. 139 140 # 2) 察看调用这个脚本的时候是否在线, 141 # 并且如果必要的话, 可以使用合适的错误消息退出. 142 143 # 3) 用一般变量来替换掉"硬编码"的BHL domain. 144 145 # 4) 通过对'dig'命令使用"+time="选项 146 # 来给这个脚本设置一个暂停. |
想获得比上边这个脚本更详细的版本, 请参考例子 A-28.
跟踪包发送到远端主机过程中的路由信息. 这个命令在LAN, WAN, 或者在Internet上都可以正常工作. 远端主机可以通过IP地址来指定. 这个命令的输出也可以通过管道中的grep或sed命令来过滤.
bash$ traceroute 81.9.6.2 traceroute to 81.9.6.2 (81.9.6.2), 30 hops max, 38 byte packets 1 tc43.xjbnnbrb.com (136.30.178.8) 191.303 ms 179.400 ms 179.767 ms 2 or0.xjbnnbrb.com (136.30.178.1) 179.536 ms 179.534 ms 169.685 ms 3 192.168.11.101 (192.168.11.101) 189.471 ms 189.556 ms * ... |
广播一个"ICMP ECHO_REQUEST"包到其他主机上, 既可以是本地网络也可以是远端网络. 这是一个测试网络连接的诊断工具, 应该小心使用.
如果ping成功之行, 那么返回的退出状态码为0. 可以用在脚本的测试语句中.
bash$ ping localhost PING localhost.localdomain (127.0.0.1) from 127.0.0.1 : 56(84) bytes of data. 64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=0 ttl=255 time=709 usec 64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=1 ttl=255 time=286 usec --- localhost.localdomain ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max/mdev = 0.286/0.497/0.709/0.212 ms |
取得网络上的用户信息. 另外这个命令可以显示一个用户的~/.plan, ~/.project, 和~/.forward文件, 当然, 前提是如果这些文件存在的话.
bash$ finger Login Name Tty Idle Login Time Office Office Phone bozo Bozo Bozeman tty1 8 Jun 25 16:59 bozo Bozo Bozeman ttyp0 Jun 25 16:59 bozo Bozo Bozeman ttyp1 Jun 25 17:07 bash$ finger bozo Login: bozo Name: Bozo Bozeman Directory: /home/bozo Shell: /bin/bash Office: 2355 Clown St., 543-1234 On since Fri Aug 31 20:13 (MST) on tty1 1 hour 38 minutes idle On since Fri Aug 31 20:13 (MST) on pts/0 12 seconds idle On since Fri Aug 31 20:13 (MST) on pts/1 On since Fri Aug 31 20:31 (MST) on pts/2 1 hour 16 minutes idle No mail. No Plan. |
出于安全上的考虑, 许多网络都禁用了finger, 以及和它相关的幽灵进程. [1]
修改finger命令所显示出来的用户信息.
验证一个互联网的e-mail地址.
sx和rx命令使用xmodem协议, 置服务来向远端主机传输文件和接收文件. 这些都是通讯安装包的一般部分, 比如minicom.
sz和rz命令使用zmodem协议, 设置服务来向远端主机传输文件和接收文件. Zmodem协议在某些方面比xmodem协议强, 比如使用更快的传输波特率, 并且可以对中断的文件进行续传. 与sx和rx一样, 这些都是通讯安装包的一般部分.
向远端服务器上传或下载的工具, 也是一种协议. 一个ftp会话可以写到脚本中自动运行. (请参考例子 17-6, 例子 A-4, 和例子 A-13).
uucp: UNIX到UNIX拷贝. 这是一个通讯安装包, 目的是为了在UNIX服务器之间传输文件. 使用shell脚本来处理uucp命令序列是一种有效的方法.
因为互联网和电子邮件的出现, uucp现在看起来已经很落伍了, 但是这个命令在互联网连接不可用或者不适合使用的地方, 这个命令还是可以完美的运行. uucp的优点就是它的容错性, 即使有一个服务将拷贝操作中断了, 那么当连接恢复的时候, 这个命令还是可以在中断的地方续传.
---
uux: UNIX到UNIX执行. 在远端系统上执行一个命令. 这个命令是uucp包的一部分.
---
cu: Call Up 一个远端系统并且作为一个简单终端进行连接. 这是一个telnet的缩减版本. 这个命令是uucp包的一部分.
连接远端主机的工具和协议.
telnet协议本身包含安全漏洞, 因此我们应该适当的避免使用. |
wget工具使用非交互的形式从web或ftp站点上取得或下载文件. 在脚本中使用正好.
1 wget -p http://www.xyz23.com/file01.html 2 # -p或--page-requisite选项将会使得wget取得所有在显示指定页时 3 #+ 所需要的文件. (译者: 比如内嵌图片和样式表等.) 4 5 wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE 6 # -r选项将会递归的从指定站点 7 #+ 上下载所有连接. |
例子 12-38. 获得一份股票报价
1 #!/bin/bash 2 # quote-fetch.sh: 下载一份股票报价. 3 4 5 E_NOPARAMS=66 6 7 if [ -z "$1" ] #必须指定需要获取的股票(代号). 8 then echo "Usage: `basename $0` stock-symbol" 9 exit $E_NOPARAMS 10 fi 11 12 stock_symbol=$1 13 14 file_suffix=.html 15 # 获得一个HTML文件, 所以要正确命名它. 16 URL='http://finance.yahoo.com/q?s=' 17 # Yahoo金融板块, 后缀是股票查询. 18 19 # ----------------------------------------------------------- 20 wget -O ${stock_symbol}${file_suffix} "${URL}${stock_symbol}" 21 # ----------------------------------------------------------- 22 23 24 # 在http://search.yahoo.com上查询相关材料: 25 # ----------------------------------------------------------- 26 # URL="http://search.yahoo.com/search?fr=ush-news&p=${query}" 27 # wget -O "$savefilename" "${URL}" 28 # ----------------------------------------------------------- 29 # 保存相关URL的列表. 30 31 exit $? 32 33 # 练习: 34 # ----- 35 # 36 # 1) 添加一个测试来验证用户是否在线. 37 # (暗示: 对"ppp"或"connect"来分析'ps -ax'的输出. 38 # 39 # 2) 修改这个脚本, 让这个脚本具有获得本地天气预报的能力, 40 #+ 将用户的zip code作为参数. |
lynx是一个网页浏览器,
也是一个文件浏览器. 它可以(通过使用-dump
选项)在脚本中使用. 它的作用是可以非交互的从Web或ftp站点上获得文件.
1 lynx -dump http://www.xyz23.com/file01.html >$SAVEFILE |
使用-traversal
选项,
lynx将会从参数中指定的HTTP URL开始,
"遍历"指定服务器上的所有连接.
如果与-crawl
选项一起用的话, 将会把每个输出的页面文本都放到一个log文件中.
远端登陆, 在远端的主机上开启一个会话. 这个命令存在安全隐患, 所以要使用ssh来代替.
远端shell, 在远端的主机上执行命令. 这个命令存在安全隐患, 所以要使用ssh来代替.
远端拷贝, 在网络上的不同主机间拷贝文件.
远端同步, 在网络上的不同主机间(同步)更新文件.
bash$ rsync -a ~/sourcedir/*txt /node1/subdirectory/ |
例子 12-39. 更新FC4(Fedora 4)
1 #!/bin/bash 2 # fc4upd.sh 3 4 # 脚本作者: Frank Wang. 5 # 本书作者作了少量修改. 6 # 授权在本书中使用. 7 8 9 # 使用rsync命令从镜像站点上下载Fedora 4的更新. 10 # 为了节省空间, 如果有多个版本存在的话, 11 #+ 只下载最新的包. 12 13 URL=rsync://distro.ibiblio.org/fedora-linux-core/updates/ 14 # URL=rsync://ftp.kddilabs.jp/fedora/core/updates/ 15 # URL=rsync://rsync.planetmirror.com/fedora-linux-core/updates/ 16 17 DEST=${1:-/var/www/html/fedora/updates/} 18 LOG=/tmp/repo-update-$(/bin/date +%Y-%m-%d).txt 19 PID_FILE=/var/run/${0##*/}.pid 20 21 E_RETURN=65 # 某些意想不到的错误. 22 23 24 # 一般rsync选项 25 # -r: 递归下载 26 # -t: 保存时间 27 # -v: verbose 28 29 OPTS="-rtv --delete-excluded --delete-after --partial" 30 31 # rsync include模式 32 # 开头的"/"会导致绝对路径名匹配. 33 INCLUDE=( 34 "/4/i386/kde-i18n-Chinese*" 35 # ^ ^ 36 # 双引号是必须的, 用来防止globbing. 37 ) 38 39 40 # rsync exclude模式 41 # 使用"#"临时注释掉一些不需要的包. 42 EXCLUDE=( 43 /1 44 /2 45 /3 46 /testing 47 /4/SRPMS 48 /4/ppc 49 /4/x86_64 50 /4/i386/debug 51 "/4/i386/kde-i18n-*" 52 "/4/i386/openoffice.org-langpack-*" 53 "/4/i386/*i586.rpm" 54 "/4/i386/GFS-*" 55 "/4/i386/cman-*" 56 "/4/i386/dlm-*" 57 "/4/i386/gnbd-*" 58 "/4/i386/kernel-smp*" 59 # "/4/i386/kernel-xen*" 60 # "/4/i386/xen-*" 61 ) 62 63 64 init () { 65 # 让管道命令返回可能的rsync错误, 比如, 网络延时(stalled network). 66 set -o pipefail 67 68 TMP=${TMPDIR:-/tmp}/${0##*/}.$$ # 保存精炼的下载列表. 69 trap "{ 70 rm -f $TMP 2>/dev/null 71 }" EXIT # 删除存在的临时文件. 72 } 73 74 75 check_pid () { 76 # 检查进程是否存在. 77 if [ -s "$PID_FILE" ]; then 78 echo "PID file exists. Checking ..." 79 PID=$(/bin/egrep -o "^[[:digit:]]+" $PID_FILE) 80 if /bin/ps --pid $PID &>/dev/null; then 81 echo "Process $PID found. ${0##*/} seems to be running!" 82 /usr/bin/logger -t ${0##*/} \ 83 "Process $PID found. ${0##*/} seems to be running!" 84 exit $E_RETURN 85 fi 86 echo "Process $PID not found. Start new process . . ." 87 fi 88 } 89 90 91 # 根据上边的模式, 92 #+ 设置整个文件的更新范围, 从root或$URL开始. 93 set_range () { 94 include= 95 exclude= 96 for p in "${INCLUDE[@]}"; do 97 include="$include --include \"$p\"" 98 done 99 100 for p in "${EXCLUDE[@]}"; do 101 exclude="$exclude --exclude \"$p\"" 102 done 103 } 104 105 106 # 获得并提炼rsync更新列表. 107 get_list () { 108 echo $$ > $PID_FILE || { 109 echo "Can't write to pid file $PID_FILE" 110 exit $E_RETURN 111 } 112 113 echo -n "Retrieving and refining update list . . ." 114 115 # 获得列表 -- 作为单个命令来运行rsync的话需要'eval'. 116 # $3和$4是文件创建的日期和时间. 117 # $5是完整的包名字. 118 previous= 119 pre_file= 120 pre_date=0 121 eval /bin/nice /usr/bin/rsync \ 122 -r $include $exclude $URL | \ 123 egrep '^dr.x|^-r' | \ 124 awk '{print $3, $4, $5}' | \ 125 sort -k3 | \ 126 { while read line; do 127 # 获得这段运行的秒数, 过滤掉不用的包. 128 cur_date=$(date -d "$(echo $line | awk '{print $1, $2}')" +%s) 129 # echo $cur_date 130 131 # 取得文件名. 132 cur_file=$(echo $line | awk '{print $3}') 133 # echo $cur_file 134 135 # 如果可能的话, 从文件名中取得rpm的包名字. 136 if [[ $cur_file == *rpm ]]; then 137 pkg_name=$(echo $cur_file | sed -r -e \ 138 's/(^([^_-]+[_-])+)[[:digit:]]+\..*[_-].*$/\1/') 139 else 140 pkg_name= 141 fi 142 # echo $pkg_name 143 144 if [ -z "$pkg_name" ]; then # 如果不是一个rpm文件, 145 echo $cur_file >> $TMP #+ 然后添加到下载列表里. 146 elif [ "$pkg_name" != "$previous" ]; then # 发现一个新包. 147 echo $pre_file >> $TMP # 输出最新的文件. 148 previous=$pkg_name # 保存当前状态. 149 pre_date=$cur_date 150 pre_file=$cur_file 151 elif [ "$cur_date" -gt "$pre_date" ]; then # 如果是相同的包, 但是这个包更新一些, 152 pre_date=$cur_date #+ 那么就更新最新的. 153 pre_file=$cur_file 154 fi 155 done 156 echo $pre_file >> $TMP # TMP现在包含所有 157 #+ 提炼过的列表. 158 # echo "subshell=$BASH_SUBSHELL" 159 160 } # 这里的大括号是为了让最后这句"echo $pre_file >> $TMP" 161 # 也能与整个循环一起放到同一个子shell ( 1 )中. 162 163 RET=$? # 取得管道命令的返回状态. 164 165 [ "$RET" -ne 0 ] && { 166 echo "List retrieving failed with code $RET" 167 exit $E_RETURN 168 } 169 170 echo "done"; echo 171 } 172 173 # 真正的rsync下载部分. 174 get_file () { 175 176 echo "Downloading..." 177 /bin/nice /usr/bin/rsync \ 178 $OPTS \ 179 --filter "merge,+/ $TMP" \ 180 --exclude '*' \ 181 $URL $DEST \ 182 | /usr/bin/tee $LOG 183 184 RET=$? 185 186 # --filter merge,+/ 对于这个目的来说, 这句是至关重要的. 187 # + 修饰语意为着包含, / 意味着绝对路径. 188 # 然后$TMP中排过序的列表将会包含升序的路径名, 189 #+ 并从"简化的流程"(shortcutting the circuit)中阻止下边的 --exclude '*'. 190 191 echo "Done" 192 193 rm -f $PID_FILE 2>/dev/null 194 195 return $RET 196 } 197 198 # ------- 199 # Main 200 init 201 check_pid 202 set_range 203 get_list 204 get_file 205 RET=$? 206 # ------- 207 208 if [ "$RET" -eq 0 ]; then 209 /usr/bin/logger -t ${0##*/} "Fedora update mirrored successfully." 210 else 211 /usr/bin/logger -t ${0##*/} "Fedora update mirrored with failure code: $RET" 212 fi 213 214 exit $RET |
在使用rcp, rsync, 还有另外一些有安全问题的类似工具的时候, 一定要小心, 因为将这些工具用在shell脚本中是不明智的. 你应该考虑使用ssh, scp, 或者expect脚本来代替这些不安全的工具.
安全shell, 登陆远端主机并在其上运行命令. 这个工具具有身份认证和加密的功能, 可以安全的替换telnet, rlogin, rcp, 和rsh等工具. 请参考这个工具的man页来获取详细信息.
例子 12-40. 使用ssh
1 #!/bin/bash 2 # remote.bash: 使用ssh. 3 4 # 这个例子是Michael Zick编写的. 5 # 授权在本书中使用. 6 7 8 # 假设的一些前提: 9 # --------------- 10 # fd-2(文件描述符2)的内容并没有被丢弃( '2>/dev/null' ). 11 # ssh/sshd假设stderr ('2')将会显示给用户. 12 # 13 # 假设sshd正运行在你的机器上. 14 # 对于绝大多数'标准'的发行版, 都是有sshd的, 15 #+ 并且没有稀奇古怪的ssh-keygen. 16 17 # 在你的机器上从命令行中试着运行一下ssh: 18 # 19 # $ ssh $HOSTNAME 20 # 不需要特别的设置, 也会要求你输入密码. 21 # 接下来输入密码, 22 # 完成后, $ exit 23 # 24 # 能够正常运行么? 如果正常的话, 接下来你可以获得更多的乐趣了. 25 26 # 尝试在你的机器上以'root'身份来运行ssh: 27 # 28 # $ ssh -l root $HOSTNAME 29 # 当要求询问密码时, 输入root的密码, 注意别输入你的用户密码. 30 # Last login: Tue Aug 10 20:25:49 2004 from localhost.localdomain 31 # 完成后键入'exit'. 32 33 # 上边的动作将会带给你一个交互的shell. 34 # 也可以在'single command'模式下建立sshd, 35 #+ 但是这已经超出本例所讲解的范围了. 36 # 唯一需要注意的是, 下面的命令都可以运行在 37 #+ 'single command'模式下. 38 39 40 # 基本的, 写stdout(本地)命令. 41 42 ls -l 43 44 # 这样远端机器上就会执行相同的命令. 45 # 如果你想的话, 可以传递不同的'USERNAME'和'HOSTNAME': 46 USER=${USERNAME:-$(whoami)} 47 HOST=${HOSTNAME:-$(hostname)} 48 49 # 现在, 在远端主机上执行上边的命令, 50 #+ 当然, 所有的传输都会被加密. 51 52 ssh -l ${USER} ${HOST} " ls -l " 53 54 # 期望的结果就是在远端主机上列出 55 #+ 你的用户名所拥有的主目录下的所有文件. 56 # 如果想看点不一样的东西, 57 #+ 那就在别的地方运行这个脚本, 别在你自己的主目录下运行这个脚本. 58 59 # 换句话说, Bash命令已经作为一个引用行 60 #+ 被传递到了远端shell中, 这样远端机器就会运行它. 61 # 在这种情况下, sshd代表你运行了' bash -c "ls -l" '. 62 63 # 如果你想不输入密码, 64 #+ 或者想更详细的了解相关的问题, 请参考: 65 #+ man ssh 66 #+ man ssh-keygen 67 #+ man sshd_config. 68 69 exit 0 |
在循环中, ssh可能会引起一些异常问题.
根据comp.unix上的shell文档 Usenet post所描述的内容,
ssh继承了循环的stdin.
为了解决这个问题,
请使用ssh的 感谢, Jason Bechtel, 为我们指出这个问题. |
安全拷贝, 在功能上与rcp很相似, 就是在两个不同的网络主机之间拷贝文件, 但是要使用鉴权的方式, 并且要使用与ssh类似的安全层.
这是一个端到端通讯的工具. 这个工具可以从你的终端上(console或者xterm)发送整行数据到另一个用户的终端上. mesg命令当然也可以用来禁用对于一个终端的写权限.
因为write命令是需要交互的, 所以这个命令在脚本中很少使用.
用来配置网络适配器(使用DHCP)的命令行工具. 这个命令对于红帽发行版来说是内置的.
发送或者读取e-mail消息.
如果把这个命令行的mail客户端当成一个脚本中的命令来使用的话, 效果非常好.
例子 12-41. 一个mail自身的脚本
1 #!/bin/sh 2 # self-mailer.sh: mail自身的脚本. 3 4 adr=${1:-`whoami`} # 如果没有指定的话, 默认是当前用户. 5 # 键入'self-mailer.sh wiseguy@superdupergenius.com' 6 #+ 将脚本发送到这个地址. 7 # 如果只键入'self-mailer.sh'(不给参数)的话, 8 #+ 那么这个脚本就会被发送给调用者, 比如, 比如, bozo@localhost.localdomain. 9 # 10 # 如果想了解${parameter:-default}结构的更多细节, 11 #+ 请参考"变量重游"那章中的 12 #+ "参数替换"小节. 13 14 # ============================================================================ 15 cat $0 | mail -s "Script \"`basename $0`\" has mailed itself to you." "$adr" 16 # ============================================================================ 17 18 # -------------------------------------------- 19 # 来自self-mailing脚本的一份祝福. 20 # 一个喜欢恶搞的家伙运行了这个脚本, 21 #+ 这导致了他自己收到了这份mail. 22 # 显然的, 有些人确实没什么事好做, 23 #+ 就只能浪费他们自己的时间玩了. 24 # -------------------------------------------- 25 26 echo "At `date`, script \"`basename $0`\" mailed to "$adr"." 27 28 exit 0 |
与mail命令很相似, mailto可以使用命令行或在脚本中发送e-mail消息. 而且mailto也可以发送MIME(多媒体)消息.
这个工具可以自动回复e-mail给发送者, 表示邮件的接受者正在度假暂时无法收到邮件. 这个工具与sendmail一起运行于网络上, 并且这个工具不支持拨号的POPmail帐号.
[1] | 一个幽灵进程指的是并未附加在终端会话中的后台进程. 幽灵进程在指定的时间执行指定的服务, 或者由特定的事件触发来执行指定的服务. 希腊文中的"daemon"意思是幽灵, 这个词充满了神秘感和神奇的力量, 在UNIX中幽灵进程总是在后台默默地执行着分配给它们的任务. |