下边命令中的某几个命令你会在追踪垃圾邮件练习中找到其用法, 用来进行网络数据的转换和分析.
通过名字或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中幽灵进程总是在后台默默地执行着分配给它们的任务. |