Advanced Bash-Scripting Guide: An in-depth exploration of the art of shell scripting | ||
---|---|---|
Prev | Chapter 12. External Filters, Programs and Commands | Next |
Certain of the following commands find use in chasing spammers, as well as in network data transfer and analysis.
Searches for information about an Internet host by name or IP address, using DNS.
bash$ host surfacemail.com surfacemail.com. has address 202.92.42.236 |
Displays IP information for a host. With the -h option, ipcalc does a reverse DNS lookup, finding the name of the host (server) from the IP address.
bash$ ipcalc -h 202.92.42.236 HOSTNAME=surfacemail.com |
Do an Internet "name server lookup" on a host by IP address. This is essentially equivalent to ipcalc -h or dig -x . The command may be run either interactively or noninteractively, i.e., from within a script.
The nslookup command has allegedly been "deprecated," but it still has its uses.
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. Similar to nslookup, dig does an Internet "name server lookup" on a host. May be run either interactively or noninteractively, i.e., from within a script.
Some interesting options to dig are +time=N for setting a query timeout to N seconds, +nofail for continuing to query servers until a reply is received, and -x for doing a reverse address lookup.
Compare the output of dig -x with ipcalc -h and 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 |
Example 12-36. Finding out where to report a spammer
1 #!/bin/bash 2 # spam-lookup.sh: Look up abuse contact to report a spammer. 3 # Thanks, Michael Zick. 4 5 # Check for command-line arg. 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 # Also try: 17 # dig +nssearch $1 18 # Tries to find "authoritative name servers" and display SOA records. 19 20 # The following also works: 21 # whois -h whois.abuse.net $1 22 # ^^ ^^^^^^^^^^^^^^^ Specify host. 23 # Can even lookup multiple spammers with this, i.e." 24 # whois -h whois.abuse.net $spamdomain1 $spamdomain2 . . . 25 26 27 # Exercise: 28 # -------- 29 # Expand the functionality of this script 30 #+ so that it automatically e-mails a notification 31 #+ to the responsible ISP's contact address(es). 32 # Hint: use the "mail" command. 33 34 exit $? 35 36 # spam-lookup.sh chinatietong.com 37 # A known spam domain. 38 39 # "crnet_mgr@chinatietong.com" 40 # "crnet_tec@chinatietong.com" 41 # "postmaster@chinatietong.com" 42 43 44 # For a more elaborate version of this script, 45 #+ see the SpamViz home page, http://www.spamviz.net/index.html. |
Example 12-37. Analyzing a spam domain
1 #! /bin/bash 2 # is-spammer.sh: Identifying spam domains 3 4 # $Id: is-spammer, v 1.4 2004/09/01 19:37:52 mszick Exp $ 5 # Above line is RCS ID info. 6 # 7 # This is a simplified version of the "is_spammer.bash 8 #+ script in the Contributed Scripts appendix. 9 10 # is-spammer <domain.name> 11 12 # Uses an external program: 'dig' 13 # Tested with version: 9.2.4rc5 14 15 # Uses functions. 16 # Uses IFS to parse strings by assignment into arrays. 17 # And even does something useful: checks e-mail blacklists. 18 19 # Use the domain.name(s) from the text body: 20 # http://www.good_stuff.spammer.biz/just_ignore_everything_else 21 # ^^^^^^^^^^^ 22 # Or the domain.name(s) from any e-mail address: 23 # Really_Good_Offer@spammer.biz 24 # 25 # as the only argument to this script. 26 #(PS: have your Inet connection running) 27 # 28 # So, to invoke this script in the above two instances: 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 # Field separator for dotted decimal ip addresses 39 ADR_IFS=${No_WSP}'.' 40 41 # Get the dns text resource record. 42 # get_txt <error_code> <list_query> 43 get_txt() { 44 45 # Parse $1 by assignment at the dots. 46 local -a dns 47 IFS=$ADR_IFS 48 dns=( $1 ) 49 IFS=$WSP_IFS 50 if [ "${dns[0]}" == '127' ] 51 then 52 # See if there is a reason. 53 echo $(dig +short $2 -t txt) 54 fi 55 } 56 57 # Get the dns address resource record. 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 # If reply might be an error code . . . 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 # Need to get the IP address from the name. 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 # A valid reply is at least 4 digits plus 3 dots. 83 if [ ${#ip_adr} -gt 6 ] 84 then 85 echo 86 declare query 87 88 # Parse by assignment at the dots. 89 declare -a dns 90 IFS=$ADR_IFS 91 dns=( ${ip_adr} ) 92 IFS=$WSP_IFS 93 94 # Reorder octets into dns query order. 95 rev_dns="${dns[3]}"'.'"${dns[2]}"'.'"${dns[1]}"'.'"${dns[0]}"'.' 96 97 # See: http://www.spamhaus.org (Conservative, well maintained) 98 echo -n 'spamhaus.org says: ' 99 echo $(chk_adr ${rev_dns} 'sbl-xbl.spamhaus.org') 100 101 # See: http://ordb.org (Open mail relays) 102 echo -n ' ordb.org says: ' 103 echo $(chk_adr ${rev_dns} 'relays.ordb.org') 104 105 # See: http://www.spamcop.net/ (You can report spammers here) 106 echo -n ' spamcop.net says: ' 107 echo $(chk_adr ${rev_dns} 'bl.spamcop.net') 108 109 # # # other blacklist operations # # # 110 111 # See: http://cbl.abuseat.org. 112 echo -n ' abuseat.org says: ' 113 echo $(chk_adr ${rev_dns} 'cbl.abuseat.org') 114 115 # See: http://dsbl.org/usage (Various mail relays) 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 # Exercises: 135 # -------- 136 137 # 1) Check arguments to script, 138 # and exit with appropriate error message if necessary. 139 140 # 2) Check if on-line at invocation of script, 141 # and exit with appropriate error message if necessary. 142 143 # 3) Substitute generic variables for "hard-coded" BHL domains. 144 145 # 4) Set a time-out for the script using the "+time=" option 146 to the 'dig' command. |
For a much more elaborate version of the above script, see Example A-28.
Trace the route taken by packets sent to a remote host. This command works within a LAN, WAN, or over the Internet. The remote host may be specified by an IP address. The output of this command may be filtered by grep or sed in a pipe.
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 * ... |
Broadcast an "ICMP ECHO_REQUEST" packet to another machine, either on a local or remote network. This is a diagnostic tool for testing network connections, and it should be used with caution.
A successful ping returns an exit status of 0. This can be tested for in a script.
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 |
Perform a DNS (Domain Name System) lookup. The -h option permits specifying which particular whois server to query. See Example 4-6 and Example 12-36.
Retrieve information about users on a network. Optionally, this command can display a user's ~/.plan, ~/.project, and ~/.forward files, if present.
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. |
Out of security considerations, many networks disable finger and its associated daemon. [1]
Change information disclosed by the finger command.
Verify an Internet e-mail address.
The sx and rx command set serves to transfer files to and from a remote host using the xmodem protocol. These are generally part of a communications package, such as minicom.
The sz and rz command set serves to transfer files to and from a remote host using the zmodem protocol. Zmodem has certain advantages over xmodem, such as faster transmission rate and resumption of interrupted file transfers. Like sx and rx, these are generally part of a communications package.
Utility and protocol for uploading / downloading files to or from a remote host. An ftp session can be automated in a script (see Example 18-6, Example A-4, and Example A-13).
uucp: UNIX to UNIX copy. This is a communications package for transferring files between UNIX servers. A shell script is an effective way to handle a uucp command sequence.
Since the advent of the Internet and e-mail, uucp seems to have faded into obscurity, but it still exists and remains perfectly workable in situations where an Internet connection is not available or appropriate. The advantage of uucp is that it is fault-tolerant, so even if there is a service interruption the copy operation will resume where it left off when the connection is restored.
---
uux: UNIX to UNIX execute. Execute a command on a remote system. This command is part of the uucp package.
---
cu: Call Up a remote system and connect as a simple terminal. It is a sort of dumbed-down version of telnet. This command is part of the uucp package.
Utility and protocol for connecting to a remote host.
![]() | The telnet protocol contains security holes and should therefore probably be avoided. |
The wget utility non-interactively retrieves or downloads files from a Web or ftp site. It works well in a script.
1 wget -p http://www.xyz23.com/file01.html 2 # The -p or --page-requisite option causes wget to fetch all files 3 #+ required to display the specified page. 4 5 wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE 6 # The -r option recursively follows and retrieves all links 7 #+ on the specified site. |
Example 12-38. Getting a stock quote
1 #!/bin/bash 2 # quote-fetch.sh: Download a stock quote. 3 4 5 E_NOPARAMS=66 6 7 if [ -z "$1" ] # Must specify a stock (symbol) to fetch. 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 # Fetches an HTML file, so name it appropriately. 16 URL='http://finance.yahoo.com/q?s=' 17 # Yahoo finance board, with stock query suffix. 18 19 # ----------------------------------------------------------- 20 wget -O ${stock_symbol}${file_suffix} "${URL}${stock_symbol}" 21 # ----------------------------------------------------------- 22 23 24 # To look up stuff on http://search.yahoo.com: 25 # ----------------------------------------------------------- 26 # URL="http://search.yahoo.com/search?fr=ush-news&p=${query}" 27 # wget -O "$savefilename" "${URL}" 28 # ----------------------------------------------------------- 29 # Saves a list of relevant URLs. 30 31 exit $? 32 33 # Exercises: 34 # --------- 35 # 36 # 1) Add a test to ensure the user running the script is on-line. 37 # (Hint: parse the output of 'ps -ax' for "ppp" or "connect." 38 # 39 # 2) Modify this script to fetch the local weather report, 40 #+ taking the user's zip code as an argument. |
See also Example A-30 and Example A-31.
The lynx Web and file browser can be used inside a script (with the -dump option) to retrieve a file from a Web or ftp site non-interactively.
1 lynx -dump http://www.xyz23.com/file01.html >$SAVEFILE |
With the -traversal option, lynx starts at the HTTP URL specified as an argument, then "crawls" through all links located on that particular server. Used together with the -crawl option, outputs page text to a log file.
Remote login, initates a session on a remote host. This command has security issues, so use ssh instead.
Remote shell, executes command(s) on a remote host. This has security issues, so use ssh instead.
Remote copy, copies files between two different networked machines.
Remote synchronize, updates (synchronizes) files between two different networked machines.
bash$ rsync -a ~/sourcedir/*txt /node1/subdirectory/ |
Example 12-39. Updating FC4
1 #!/bin/bash 2 # fc4upd.sh 3 4 # Script author: Frank Wang. 5 # Slight stylistic modifications by ABS Guide author. 6 # Used in ABS Guide with permission. 7 8 9 # Download Fedora 4 update from mirror site using rsync. 10 # Only download latest package if multiple versions exist, 11 #+ to save space. 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 # Something unexpected happened. 22 23 24 # General rsync options 25 # -r: recursive download 26 # -t: reserve time 27 # -v: verbose 28 29 OPTS="-rtv --delete-excluded --delete-after --partial" 30 31 # rsync include pattern 32 # Leading slash causes absolute path name match. 33 INCLUDE=( 34 "/4/i386/kde-i18n-Chinese*" 35 # ^ ^ 36 # Quoting is necessary to prevent globbing. 37 ) 38 39 40 # rsync exclude pattern 41 # Temporarily comment out unwanted pkgs using "#" . . . 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 # Let pipe command return possible rsync error, e.g., stalled network. 66 set -o pipefail # Newly introduced in Bash, version 3. 67 68 TMP=${TMPDIR:-/tmp}/${0##*/}.$$ # Store refined download list. 69 trap "{ 70 rm -f $TMP 2>/dev/null 71 }" EXIT # Clear temporary file on exit. 72 } 73 74 75 check_pid () { 76 # Check if process exists. 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 # Set overall file update range starting from root or $URL, 92 #+ according to above patterns. 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 # Retrieve and refine rsync update list. 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 # Retrieve list -- 'eval' is needed to run rsync as a single command. 116 # $3 and $4 is the date and time of file creation. 117 # $5 is the full package name. 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 # Get seconds since epoch, to filter out obsolete pkgs. 128 cur_date=$(date -d "$(echo $line | awk '{print $1, $2}')" +%s) 129 # echo $cur_date 130 131 # Get file name. 132 cur_file=$(echo $line | awk '{print $3}') 133 # echo $cur_file 134 135 # Get rpm pkg name from file name, if possible. 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 # If not a rpm file, 145 echo $cur_file >> $TMP #+ then append to download list. 146 elif [ "$pkg_name" != "$previous" ]; then # A new pkg found. 147 echo $pre_file >> $TMP # Output latest file. 148 previous=$pkg_name # Save current. 149 pre_date=$cur_date 150 pre_file=$cur_file 151 elif [ "$cur_date" -gt "$pre_date" ]; then # If same pkg, but newer, 152 pre_date=$cur_date #+ then update latest pointer. 153 pre_file=$cur_file 154 fi 155 done 156 echo $pre_file >> $TMP # TMP contains ALL 157 #+ of refined list now. 158 # echo "subshell=$BASH_SUBSHELL" 159 160 } # Bracket required here to let final "echo $pre_file >> $TMP" 161 # Remained in the same subshell ( 1 ) with the entire loop. 162 163 RET=$? # Get return code of the pipe command. 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 # Real rsync download part. 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,+/ is crucial for the intention. 187 # + modifier means include and / means absolute path. 188 # Then sorted list in $TMP will contain ascending dir name and 189 #+ prevent the following --exclude '*' from "shortcutting the circuit." 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 |
Using rcp, rsync, and similar utilities with security implications in a shell script may not be advisable. Consider, instead, using ssh, scp, or an expect script.
Secure shell, logs onto a remote host and executes commands there. This secure replacement for telnet, rlogin, rcp, and rsh uses identity authentication and encryption. See its manpage for details.
Example 12-40. Using ssh
1 #!/bin/bash 2 # remote.bash: Using ssh. 3 4 # This example by Michael Zick. 5 # Used with permission. 6 7 8 # Presumptions: 9 # ------------ 10 # fd-2 isn't being captured ( '2>/dev/null' ). 11 # ssh/sshd presumes stderr ('2') will display to user. 12 # 13 # sshd is running on your machine. 14 # For any 'standard' distribution, it probably is, 15 #+ and without any funky ssh-keygen having been done. 16 17 # Try ssh to your machine from the command line: 18 # 19 # $ ssh $HOSTNAME 20 # Without extra set-up you'll be asked for your password. 21 # enter password 22 # when done, $ exit 23 # 24 # Did that work? If so, you're ready for more fun. 25 26 # Try ssh to your machine as 'root': 27 # 28 # $ ssh -l root $HOSTNAME 29 # When asked for password, enter root's, not yours. 30 # Last login: Tue Aug 10 20:25:49 2004 from localhost.localdomain 31 # Enter 'exit' when done. 32 33 # The above gives you an interactive shell. 34 # It is possible for sshd to be set up in a 'single command' mode, 35 #+ but that is beyond the scope of this example. 36 # The only thing to note is that the following will work in 37 #+ 'single command' mode. 38 39 40 # A basic, write stdout (local) command. 41 42 ls -l 43 44 # Now the same basic command on a remote machine. 45 # Pass a different 'USERNAME' 'HOSTNAME' if desired: 46 USER=${USERNAME:-$(whoami)} 47 HOST=${HOSTNAME:-$(hostname)} 48 49 # Now excute the above command line on the remote host, 50 #+ with all transmissions encrypted. 51 52 ssh -l ${USER} ${HOST} " ls -l " 53 54 # The expected result is a listing of your username's home 55 #+ directory on the remote machine. 56 # To see any difference, run this script from somewhere 57 #+ other than your home directory. 58 59 # In other words, the Bash command is passed as a quoted line 60 #+ to the remote shell, which executes it on the remote machine. 61 # In this case, sshd does ' bash -c "ls -l" ' on your behalf. 62 63 # For information on topics such as not having to enter a 64 #+ password/passphrase for every command line, see 65 #+ man ssh 66 #+ man ssh-keygen 67 #+ man sshd_config. 68 69 exit 0 |
![]() | Within a loop, ssh may cause unexpected behavior. According to a Usenet post in the comp.unix shell archives, ssh inherits the loop's stdin. To remedy this, pass ssh either the -n or -f option. Thanks, Jason Bechtel, for pointing this out. |
Secure copy, similar in function to rcp, copies files between two different networked machines, but does so using authentication, and with a security level similar to ssh.
This is a utility for terminal-to-terminal communication. It allows sending lines from your terminal (console or xterm) to that of another user. The mesg command may, of course, be used to disable write access to a terminal
Since write is interactive, it would not normally find use in a script.
A command-line utility for configuring a network adapter (using DHCP). This command is native to Red Hat centric Linux distros.
Send or read e-mail messages.
This stripped-down command-line mail client works fine as a command embedded in a script.
Example 12-41. A script that mails itself
1 #!/bin/sh 2 # self-mailer.sh: Self-mailing script 3 4 adr=${1:-`whoami`} # Default to current user, if not specified. 5 # Typing 'self-mailer.sh wiseguy@superdupergenius.com' 6 #+ sends this script to that addressee. 7 # Just 'self-mailer.sh' (no argument) sends the script 8 #+ to the person invoking it, for example, bozo@localhost.localdomain. 9 # 10 # For more on the ${parameter:-default} construct, 11 #+ see the "Parameter Substitution" section 12 #+ of the "Variables Revisited" chapter. 13 14 # ============================================================================ 15 cat $0 | mail -s "Script \"`basename $0`\" has mailed itself to you." "$adr" 16 # ============================================================================ 17 18 # -------------------------------------------- 19 # Greetings from the self-mailing script. 20 # A mischievous person has run this script, 21 #+ which has caused it to mail itself to you. 22 # Apparently, some people have nothing better 23 #+ to do with their time. 24 # -------------------------------------------- 25 26 echo "At `date`, script \"`basename $0`\" mailed to "$adr"." 27 28 exit 0 |
Similar to the mail command, mailto sends e-mail messages from the command line or in a script. However, mailto also permits sending MIME (multimedia) messages.
This utility automatically replies to e-mails that the intended recipient is on vacation and temporarily unavailable. This runs on a network, in conjunction with sendmail, and is not applicable to a dial-up POPmail account.
[1] | A daemon is a background process not attached to a terminal session. Daemons perform designated services either at specified times or explicitly triggered by certain events. The word "daemon" means ghost in Greek, and there is certainly something mysterious, almost supernatural, about the way UNIX daemons silently wander about behind the scenes, carrying out their appointed tasks. |