فصل 16- فرمان‌ها، برنامه‌ها و فیلترهای خارجی

‎16.6‎- فرمان‌های ارتباطات

برخی از فرمانهای زیر در نقل و انتقال و تجزیه و تحلیل داده‌ها در شبکه، و همچنین در شکار کردن spammerها، مورد استفاده خواهند داشت.

اطلاعات و آمار


host

با استفاده از DNS، اطلاعات یک میزبان اینترنتی را برحسب نام یا آدرس IP جستجو می‌کند.

bash$ host surfacemail.com
surfacemail.com. has address 202.92.42.236

ipcalc

اطلاعات ‎IP‎ یک میزبان را نمایش می‌دهد. فرمان ipcalc با گزینه ‎-h‎ یک جستجوی DNS معکوس، پیدا کردن نام میزبان (سرویس‌دهنده) از آدرس IP انجام می‌دهد.

bash$ ipcalc -h 202.92.42.236
HOSTNAME=surfacemail.com

nslookup

انجام یک «جستجوی نام سرویس‌دهنده» اینترنت روی یک میزبان بواسطه آدرس 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

dig

Domain Information Groper. مشابه nslookup، فرمان dig یک جستجوی نام سرویس‌دهنده روی یک میزبان انجام می‌دهد. ممکن است از خط فرمان یا از داخل یک اسکریپت اجرا گردد.

‎+time=N‎ برای تنظیم یک پرس و جوی زمان‌دار به مدت N ثانیه، ‎+nofail‎ برای ادامه پرس و جو با سرویس‌دهنده تا دریافت شدن پاسخ، و ‎-x‎ برای انجام جستجوی معکوس آدرس، برخی گزینه‌های جالب برای dig هستند.

خروجی ‎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

مثال ‎16-40‎. یافتن جایی برای گزارش دادن یک spam کننده

#!/bin/bash
# ‎spam-lookup.sh:  .spammer‎ جستجوی آدرس یک سوء استفاده کننده جهت گزارش کردن یک
#با تشکر از ‎Michael Zick‎.

# کنترل برای شناسه خط فرمان.
ARGCOUNT=1
E_WRONGARGS=85
if [ $# -ne "$ARGCOUNT" ]
then
  echo "Usage: `basename $0` domain-name"
  exit $E_WRONGARGS
fi


dig +short $1.contacts.abuse.net -c in -t txt
#                           این مورد را نیز امتحان کنید:
# dig +nssearch $1
#           برای یافتن «نام سرویس‌دهنده‌های معتبر» و نمایش 
#       رکوردهای ‎SOA‎ تلاش می‌کند. مورد زیر نیز کار می‌کند:
#     whois -h whois.abuse.net $1
#           ‎^^ ^^^^^^^^^^^^^^^‎            .تعیین میزبان 
#حتی می‌توان چند spammer را با این دستور جستجو کرد، یعنی
#whois -h whois.abuse.net $spamdomain1 $spamdomain2 . . .


#                          تمرین:
#             -------------------------------
# توانایی این اسکریپت را طوری بسط بدهید، که به طور خودکار
#+   به  ‎ISP‎ مسئول آدرس(های) ارتباط، گزارشی ایمیل نماید.
#                     اشاره: از فرمان ‎mail‎ استفاده کنید.

exit $?

# spam-lookup.sh chinatietong.com
#       یک دامنه spam شناخته شده.

#  "crnet_mgr@chinatietong.com"
#  "crnet_tec@chinatietong.com"
# "postmaster@chinatietong.com"


# برای یک نگارش تفصیلی‌تر از این اسکریپت صفحه خانگی ‎SpamViz‎ 
#+  در ‎http://www.spamviz.net/index را مشاهده نمایید‎.

مثال ‎16-41‎. تجزیه و تحلیل یک دامنه spam

#! /bin/bash
#            ‎is-spammer.sh:‎         spam شناسایی نمودن دامنه‌های

#       $Id: is-spammer, v 1.4 2004/09/01 19:37:52 mszick Exp $
#   سطر فوق اطلاعات شماره شناسایی سیستم کنترل بازنگری (‎‎RCS‎)‏‎ است.
#
#   این یک نگارش ساده شده از اسکریپتِ «‎is_spammer.bash‎» موجود در
#+                               پیوست «اسکریپت‌های اهدایی» است.

#  is-spammer <domain.name>

#                        یک برنامه خارجی (dig) را به کار می‌برد:
#                                      تست شده با نگارش ‎9.2.4rc5‎

#                                       از توابع استفاده می‌کند.
# از متغیر ‎IFS‎ برای تجزیه رشته‌ها به داخل آرایه‌ها استفاده می‌کند.
# کار مفیدی هم انجام می‌دهد: لیست‌های سیاه ‎e-mail‎ را کنترل می‌کند.

#                               ‎domain.name‎(ها) را از بدنه متن:
# http://www.good_stuff.spammer.biz/just_ignore_everything_else
#                       ^^^^^^^^^^^
#        یا از هر آدرس ‎e-mail‎ مثل Really_Good_Offer@spammer.biz
#                          ^^^^^^^^^^^  
#                  به عنوان تنها شناسه این اسکریپت استفاده کنید.
#                       (توجه:  ارتباط اینترنتی شما برقرار باشد)
#
#           بنابراین، برای فراخوانی این اسکریپت در دو نمونه فوق:
# is-spammer.sh spammer.biz


# Whitespace == :Space:Tab:Line Feed:Carriage Return:
WSP_IFS=$'\x20'$'\x09'$'\x0A'$'\x0D'

# No Whitespace == Line Feed:Carriage Return
No_WSP=$'\x0A'$'\x0D'

#  جداکننده فیلد برای آدرس‌های IP دارای نقطه اعشاری
ADR_IFS=${No_WSP}'.'

#                      به دست آوردن متن رکورد ‎dns‎.
# get_txt <error_code> <list_query>
get_txt() {

    #                      تجزیه ‎$1‎ از محل نقطه‌ها.
    local -a dns
    IFS=$ADR_IFS
    dns=( $1 )
    IFS=$WSP_IFS
    if [ "${dns[0]}" == '127' ]
    then
        # See if there is a reason.
        echo $(dig +short $2 -t txt)
    fi
}

#                     به دست آوردن آدرس رکورد ‎dns‎.
# chk_adr <rev_dns> <list_server>
chk_adr() {
    local reply
    local server
    local reason

    server=${1}${2}
    reply=$( dig +short ${server} )

    #           اگر پاسخ احتمالاً یک کد خطا باشد . . .
    if [ ${#reply} -gt 6 ]
    then
        reason=$(get_txt ${reply} ${server} )
        reason=${reason:-${reply}}
    fi
    echo ${reason:-' not blacklisted.'}
}

#             به دست آوردن آدرس ‎IP‎ از نام، لازم است.
echo 'Get address of: '$1
ip_adr=$(dig +short $1)
dns_reply=${ip_adr:-' no answer '}
echo ' Found address: '${dns_reply}

#یک پاسخ معتبر، حداقل چهار رقم به‌اضافه سه نقطه است.
if [ ${#ip_adr} -gt 6 ]
then
    echo
    declare query

    # تجزیه ‎$1‎ از محل نقطه‌ها.
    declare -a dns
    IFS=$ADR_IFS
    dns=( ${ip_adr} )
    IFS=$WSP_IFS

    # دوباره مرتب کردن قسمت‌ها به صورت همان dns اولیه.
    rev_dns="${dns[3]}"'.'"${dns[2]}"'.'"${dns[1]}"'.'"${dns[0]}"'.'

# ‎http://www.spamhaus.org‎ را ببینید (سنتی، خوب نگهداری شده)
    echo -n 'spamhaus.org says: '
    echo $(chk_adr ${rev_dns} 'sbl-xbl.spamhaus.org')

# این را ملاحظه کنید: ‎http://ordb.org (Open mail relays)‎
    echo -n '   ordb.org  says: '
    echo $(chk_adr ${rev_dns} 'relays.ordb.org')

# ‎http://www.spamcop.net‎ را ببینید (‎spammer‎ها را اینجا گزارش کنید)
    echo -n ' spamcop.net says: '
    echo $(chk_adr ${rev_dns} 'bl.spamcop.net')

#  # # # # سایر عملیات لیست سیاه # # #

# ‎http://cbl.abuseat.org‎ را مشاهده کنید.
    echo -n ' abuseat.org says: '
    echo $(chk_adr ${rev_dns} 'cbl.abuseat.org')

#‎http://dsbl.org/usage‎ را ببینید (مخابره mail گوناگون)
    echo
    echo 'Distributed Server Listings'
    echo -n '       list.dsbl.org says: '
    echo $(chk_adr ${rev_dns} 'list.dsbl.org')

    echo -n '   multihop.dsbl.org says: '
    echo $(chk_adr ${rev_dns} 'multihop.dsbl.org')

    echo -n 'unconfirmed.dsbl.org says: '
    echo $(chk_adr ${rev_dns} 'unconfirmed.dsbl.org')

else
    echo
    echo 'Could not use that address.'
fi

exit 0

#                                تمرین‌ها:
#         -----------------------------------------------

#   ‎(1‎ کنترل شناسه‌های اسکریپت و در صورت لزوم، خروج با پیغام خطای مناسب.

#  ‎(2‎ کنترل برقرار بودن ارتباط اینترنتی موقع فراخوانی اسکریپت و در صورت
#                                 لزوم خارج شدن با یک پیغام خطای مناسب.

#   ‎(3‎ دامنه‌های درج شده در میان کد را با متغیرهای عمومی جایگزین نمایید.

# ‎(4‎ برای اسکریپت با استفاده از گزینه ‎+time=‎ فرمان dig مهلت تعیین کنید.

برای نگارشی از اسکریپت فوق که دارای جزییات بیشتری است، مثال ‎A-28‎ را مشاهده کنید.

traceroute

ردیابی مسیر پیموده شده توسط بسته‌های کوچک فرستاده شده به یک میزبان راه دور. این فرمان داخل یک شبکه ‎LAN‎‏، ‎WAN‎، یا روی اینترنت کار می‌کند. میزبان راه دور ممکن است توسط یک آدرس 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 *
...

ping

انتشار یک بسته کوچک ‎ICMP ECHO_REQUEST‎ به یک ماشین دیگر، یا روی یک شبکه محلی یا شبکه راه دور. این یک ابزار تشخیصی برای بررسی ارتباطات شبکه است، و باید با هشیاری به کار برود.

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

یک ping موفق، یک وضعیت خروج 0 برگشت می‌دهد. در یک اسکریپت، این وضعیت خروج می‌تواند مورد بررسی قرار گیرد.

HNAME=news-15.net  # spammer بدنام.
# HNAME=$HOST      # اشکال‌زدایی: با ‎localhost‎ بررسی کنید.
  count=2          #فقط دو ping  ارسال شود.

if [[ `ping -c $count "$HNAME"` ]]
then
  echo ""$HNAME" still up and broadcasting spam your way."
else
  echo ""$HNAME" seems to be down. Pity."
fi

whois

یک جستجوی ‎DNS (Domain Name System)‎ انجام می‌دهد. گزینه ‎-h‎ مشخص نمودن سرویس‌دهنده whois ویژه‌ای را برای پرس و جو اجازه می‌دهد. مثال ‎4-6‎ و مثال ‎16-40‎ را مشاهده نمایید.

finger

اطلاعاتی در باره کاربران روی شبکه به دست می‌آورد. به طور انتخابی، این فرمان می‌تواند فایل‌های ‎~/.plan‎‏، ‎~/.project‎، و ‎~/.forward‎ را اگر موجود باشند، نمایش بدهد.

bash$ finger

 Login  Name           Tty      Idle  Login Time   Office     Office Phone
 bozo   Bozo Bozeman   tty1        8  Jun 25 16:59                (:0)
 bozo   Bozo Bozeman   ttyp0          Jun 25 16:59                (:0.0)
 bozo   Bozo Bozeman   ttyp1          Jun 25 17:07                (:0.0)


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
 Mail last read Tue Jul  3 10:08 2007 (MST) 
 No Plan.

بواسطه ملاحظات امنیتی، بسیاری از شبکه‌ها finger و سرویس‌های کمکی آن را غیر فعال می‌کنند. ‎[1]‎

chfn

اطلاعات فاش شونده به وسیله فرمان finger را تغییر می‌دهد.

vrfy

صحت یک آدرس ‎e-mail‎ اینترنتی را بررسی می‌کند.

به نظر می‌رسد این فرمان در توزیع‌های جدیدتر لینوکس غایب باشد.

دستیابی میزبان راه دور


sx‏، rx

مجموعه فرمان sx و rx برای انتقال فایل مطابق قرارداد xmodem به میزبان راه دور یا برعکس به کار می‌رود. به طور معمول اینها بخشی از یک بسته ارتباطات، مانند minicom هستند.

sz‏، rz

مجموعه فرمان sz و rz در انتقال فایل به میزبان راه دور و بالعکس با استفاده از قرارداد zmodem خدمت می‌نمایند. Zmodem دارای مزایایی نسبت به xmodem است، از قبیل سرعت مخابره بیشتر و دوباره ادامه دادن انتقال فایل‌های متوقف شده. مانند sx و rx، اینها نیز معمولاً بخشی از یک بسته ارتباطات هستند.

ftp

برنامه سودمند و یک قرارداد برای ارسال و دریافت فایل‌ها به/از یک میزبان راه دور. یک نشست ‎ftp‎ می‌تواند به طور خودکار در داخل یک اسکریپت پوسته انجام شود ( مثال ‎19-6‎ و مثال ‎A-4‎ را ببینید).

uucp‏، uux‏، cu

uucp‏‏: ‎UNIX to UNIX copy‎. این یک بسته ارتباطات برای انتقال فایل بین سرویس‌دهنده‌های یونیکس است. یک اسکریپت پوسته روش کارآمدی برای به کار بردن یک رشته فرمان uucp است.

از زمان ظهور اینترنت و ‎e-mail‎‏، به نظر می‌رسد uucp در گمنامی به فراموشی سپرده شده است، اما این برنامه هنوز و جود دارد و برای وضعیت‌هایی که در آنها یک ارتباط اینترنتی در دسترس یا متناسب نیست باقی می‌ماند. مزیت uucp آن است که ‎fault-tolerant‎ (بردبار با خطا) است، بنابراین حتی اگر یک وقفه سرویس وجود داشته باشد، وقتی ارتباط ترمیم می‌شود عمل کپی از جایی که قطع شده ادامه خواهد یافت.

---

uux‏: ‎UNIX to UNIX execute‎. اجرای یک فرمان روی سیستم راه دور. این فرمان بخشی از بسته uucp است.

---

cu‏: ‎(Call Up)‎ احضار کردن یک سیستم راه دور و اتصال به عنوان یک ترمینال ساده. این یک نوع نگارش ساده شده telnet است. این فرمان نیز بخشی از بسته ارتباطات uucp است.

telnet

یک قرارداد و برنامه سودمندی برای برقراری ارتباط با یک سیستم راه دور.

Caution

پروتکل telnet شامل حفره‌های امنیتی است و بنابراین احتمالاً باید موقوف بشود. استفاده از آن در داخل یک اسکریپت پوسته پیشنهاد نمی‌شود.

wget

برنامه سودمند wget به طور غیرتعاملی فایل‌ها را از یک پایگاه وب یا ‎ftp‎ بازیابی یا دانلود می‌کند. در یک اسکریپت به خوبی عمل می‌کند.

wget -p http://www.xyz23.com/file01.html
#گزینه ‎-p‎ یا ‎--page-requisite‎ باعث می‌شود ‎wget‎ تمام فایل‌های
#+           لازم برای نمایش صفحه مشخص شده را دریافت نماید.

wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE
#گزینه ‎-r‎ تمام پیوندهای پایگاه تعیین شده را به طور بازگشتی
#+                            دنبال نموده و بازیابی می‌کند.

wget -c ftp://ftp.xyz25.net/bozofiles/filename.tar.bz2
#   گزینه ‎-c‎ به wget اجازه می‌دهد دانلود قطع شده ادامه بدهد.
# این با سرویس‌دهنده‌های ‎ftp‎ و بسیاری سایتهای HTTP کار می‌کند.

مثال ‎16-42‎. دریافت قیمت سهام

#!/bin/bash
# ‎quote-fetch.sh:‎ .دانلود یک لیست قیمت سهام


E_NOPARAMS=86

if [ -z "$1" ]  #باید سهامی(نشان) برای اخذ تعیین شود
  then echo "Usage: `basename $0` stock-symbol"
  exit $E_NOPARAMS
fi

stock_symbol=$1

file_suffix=.html
#    یک فایل HTML می‌گیرد، پس به طور مقتضی نام ببرید.
URL='http://finance.yahoo.com/q?s='
#   تابلوی سرمایه‌گذاری Yahoo، با دنباله استعلام سهام.

# -------------------------------------------------------
wget -O ${stock_symbol}${file_suffix} "${URL}${stock_symbol}"
# -------------------------------------------------------


#             برای جستجو روی ‎http://search.yahoo.com‎
# -----------------------------------------------------------
# URL="http://search.yahoo.com/search?fr=ush-news&p=${query}"
# wget -O "$savefilename" "${URL}"
# -----------------------------------------------------------
#                 لیستی از URLهای مربوط ذخیره می‌کند.

exit $?

#                             تمرین‌ها:
#            ----------------------------------------
#
# ‎(1‎ تستی جهت اطمینان از برخط بودن کاربر اجرا کننده اسکریپت اضافه کنید.
#      (اشاره: خروجی ‎ps -ax‎ را برای ‎"ppp"‎ یا ‎"connect"‎ تجزیه کنید.)
#
#    ‎(2‎ این اسکریپت را طوری ویرایش کنید که با گرفتن کد پستی به عنوان یک
#+                       شناسه، آب و هوای منطقه کاربر را گزارش کند.

همچنین مثال ‎A-30‎ و مثال ‎A-31‎ را ببینید.

lynx

فرمان lynx مرورگر Web و فایل، می‌تواند به طور غیرتعاملی در داخل یک اسکریپت (با گزینه‎-dump‎)، برای بازیابی یک فایل از یک پایگاه Web یا ftp به کار برود.

lynx -dump http://www.xyz23.com/file01.html >$SAVEFILE

با گزینه ‎-traversal‎، برنامه lynx از ‎HTTP URL‎ تعیین شده به عنوان یک شناسه شروع می‌کند، سپس به تمام پیوند‌های مستقر در آن سرویس‌دهنده بخصوص «می‌خزد». در استفاده با گزینه ‎-crawl‎، متن صفحه را در یک فایل log بیرون می‌دهد.

rlogin

لاگین راه دور، یک نشست روی میزبان راه دور آغاز می‌کند. این فرمان دارای پیامدهای امنیتی است، بنابراین به جای آن از ssh استفاده نمایید.

rsh

shell راه دور، فرمان(ها) را روی یک میزبان راه دور اجرا می‌کند. دارای پیامدهای امنیتی است، بنابراین به جای آن از ssh استفاده کنید.

rcp

کپی راه دور، فایل‌ها را میان دو ماشین متمایز شبکه شده کپی می‌کند.

rsync

هماهنگ سازی راه دور، فایل‌ها را میان دو ماشین شبکه شدهِ متمایز به روزرسانی (هماهنگ) می‌کند.

bash$ rsync -a ~/sourcedir/*txt/node1/subdirectory/

مثال ‎16-43‎. به روزرسانی ‎FC4‎ ‏(Fedora Core 4)‏

#!/bin/bash
# fc4upd.sh

#مولف اسکریپت: ‎Frank Wang‎.
#با اصلاحات نگارشی کم توسط نگارنده راهنمای ‎ABS‎.
#   در راهنمای ABS با مجوز استفاده گردیده است.


#   دانلود  update فدورا ‎Core 4‎ از سایت mirror با استفاده از rsync. 
#برای نگارش‌های جدیدتر ‎Fedora Cores -- 5, 6, . . .‎ نیز باید کار کند.‎
#   برای صرفه‌جویی، در صورت وجود چندین نگارش، فقط دانلود آخرین بسته.

URL=rsync://distro.ibiblio.org/fedora-linux-core/updates/
# URL=rsync://ftp.kddilabs.jp/fedora/core/updates/
# URL=rsync://rsync.planetmirror.com/fedora-linux-core/updates/

DEST=${1:-/var/www/html/fedora/updates/}
LOG=/tmp/repo-update-$(/bin/date +%Y-%m-%d).txt
PID_FILE=/var/run/${0##*/}.pid

E_RETURN=85        #در صورت وقوع یک مورد پیش‌بینی نشده.


#گزینه‌های عمومی rsync
#  ‎-r‎: دانلود بازگشتی
#     ‎-t‎: اختصاص زمان
#    ‎-v‎: ارایه جزییات

OPTS="-rtv --delete-excluded --delete-after --partial"

#                           الگوی مشمول ‎rsync‎
#‎slash‎ مقدم باعث انطباق نام مسیر مطلق می‌گردد.
INCLUDE=(
    "/4/i386/kde-i18n-Chinese*" 
#   ^                         ^
# نقل‌قول‌ها برای پیش‌گیری از جانشینی، لازم هستند.
) 


#                       الگوی محروم کردن ‎rsync‎
# بسته‌های ناخواسته را با استفاده از ‎#‎ موقتاً به توضیح تبدیل کنید.
EXCLUDE=(
    /1
    /2
    /3
    /testing
    /4/SRPMS
    /4/ppc
    /4/x86_64
    /4/i386/debug
   "/4/i386/kde-i18n-*"
   "/4/i386/openoffice.org-langpack-*"
   "/4/i386/*i586.rpm"
   "/4/i386/GFS-*"
   "/4/i386/cman-*"
   "/4/i386/dlm-*"
   "/4/i386/gnbd-*"
   "/4/i386/kernel-smp*"
#  "/4/i386/kernel-xen*" 
#  "/4/i386/xen-*" 
)


init () {
#اجازه بدهید فرمان لوله خطای محتمل rsync، مثلاً شبکه وامانده، را برگشت بدهد.
    set -o pipefail                  # اخیراً در ‎Bash‎ نگارش ‎3‎ معرفی شده.

    TMP=${TMPDIR:-/tmp}/${0##*/}.$$  #     ذخیره لیست تصحیح شده دانلود.
    trap "{
        rm -f $TMP 2>/dev/null
    }" EXIT                          # پاک کردن فایل موقت در زمان خروج.
}


check_pid () {
#کنترل وجود پردازش.
    if [ -s "$PID_FILE" ]; then
        echo "PID file exists. Checking ..."
        PID=$(/bin/egrep -o "^[[:digit:]]+" $PID_FILE)
        if /bin/ps --pid $PID &>/dev/null; then
            echo "Process $PID found. ${0##*/} seems to be running!"
           /usr/bin/logger -t ${0##*/} \
                 "Process $PID found. ${0##*/} seems to be running!"
            exit $E_RETURN
        fi
        echo "Process $PID not found. Start new process . . ."
    fi
}


# تنظیم کلی محدوده به روزرسانی فایل با شروع
#+        از ریشه یا ‎$URL‎ مطابق الگوهای فوق.
set_range () {
    include=
    exclude=
    for p in "${INCLUDE[@]}"; do
        include="$include --include \"$p\""
    done

    for p in "${EXCLUDE[@]}"; do
        exclude="$exclude --exclude \"$p\""
    done
}


#بازیابی و پالایش لیست به روزرسانی ‎rsync‎.
get_list () {
    echo $$ > $PID_FILE || {
        echo "Can't write to pid file $PID_FILE"
        exit $E_RETURN
    }

    echo -n "Retrieving and refining update list . . ."

    #  بازیابی لیست -- برای اجرای ‎rsync‎ به عنوان یک فرمان واحد، ‎eval‎ لازم است.
    #           ‎$3‎ و ‎$4‎ تاریخ و زمان ایجاد فایل هستند و ‎$5‎ نام کامل بسته است.
    previous=
    pre_file=
    pre_date=0
    eval /bin/nice /usr/bin/rsync \
      -r $include $exclude $URL | \
      egrep '^dr.x|^-r' | \
      awk '{print $3, $4, $5}' | \
      sort -k3 | \
      { while read line; do
         #به دست آوردن ثانیه‌ها از ‎epoch‎ برای فیلتر کردن بسته‌های از رده خارج.
         cur_date=$(date -d "$(echo $line | awk '{print $1, $2}')" +%s)
         #  echo $cur_date

         #به دست آوردن نام فایل.
         cur_file=$(echo $line | awk '{print $3}')
         #  echo $cur_file

         #             به دست آوردن نام بسته ‎rpm‎ از نام فایل، در صورت امکان.
         if [[ $cur_file == *rpm ]]; then
             pkg_name=$(echo $cur_file | sed -r -e \
                 's/(^([^_-]+[_-])+)[[:digit:]]+\..*[_-].*$/\1/')
         else
             pkg_name=
         fi
         # echo $pkg_name

         if [ -z "$pkg_name" ]; then      #             اگر یک فایل ‎rpm‎ نیست،
             echo $cur_file >> $TMP       #+ آنوقت افزودن آن به لیست دانلود.
         elif [ "$pkg_name" != "$previous" ]; then   #یک بسته جدید پیدا شده.
             echo $pre_file >> $TMP                  #     آخرین فایل خروجی.
             previous=$pkg_name                      #   ذخیره آخرین اطلاعات.
             pre_date=$cur_date
             pre_file=$cur_file
         elif [ "$cur_date" -gt "$pre_date" ]; then
                                          #   اگر همان بسته، اما جدیدتر است،
             pre_date=$cur_date           #+   آنوقت به روزرسانی آخرین مورد.
             pre_file=$cur_file
         fi
         done
         echo $pre_file >> $TMP           #اینک ‎TMP‎ شامل لیست تصفیه شده است.
         # echo "subshell=$BASH_SUBSHELL"

    }    #       لازم است براکت اینجا باشد، تا ‎echo $pre_file >> $TMP‎ پایانی،
         #              با تمام حلقه در یک پوسته فرعی ‎( 1 )‎ قرار داشته باشد.

    RET=$?                              # به دست آوردن کد برگشتی فرمان لوله.

    [ "$RET" -ne 0 ] && {
        echo "List retrieving failed with code $RET"
        exit $E_RETURN
    }

    echo "done"; echo
}

#بخش اصلی دانلود ‎rsync‎.
get_file () {

    echo "Downloading..."
    /bin/nice /usr/bin/rsync \
        $OPTS \
        --filter "merge,+/ $TMP" \
        --exclude '*'  \
        $URL $DEST     \
        | /usr/bin/tee $LOG

    RET=$?

   #      ‎--filter merge,+/‎ برای مقصود ما بسیار مهم است. توصیف‌گر
   #     ‎+‎ به معنی شامل بودن و ‎/‎ به معنی مسیر مطلق است. سپس لیست
   #    مرتب‌شده در ‎$TMP‎ شامل نام دایرکتوری‌ها به صورت صعودی خواهد
   #+بود و مانع میانبر کردن مسیر توسط ‎--exclude '*'‎ بعدی می‌شود.

    echo "Done"

    rm -f $PID_FILE 2>/dev/null

    return $RET
}

# ------------
# Main
init
check_pid
set_range
get_list
get_file
RET=$?
# ------------

if [ "$RET" -eq 0 ]; then
    /usr/bin/logger -t ${0##*/} "Fedora update mirrored successfully."
else
    /usr/bin/logger -t ${0##*/} \
    "Fedora update mirrored with failure code: $RET"
fi

exit $RET

همچنین مثال ‎A-32‎ را مشاهده کنید.

در یک اسکریپت پوسته، کاربرد rcp‏، rsync، و برنامه‌های مشابه دارای پیامدهای امنیتی ممکن است به صلاح نباشد. در عوض، کاربرد ssh‏، scp، یا یک اسکریپت expect را در نظر بگیرید.

ssh

‎Secure shell‎‏، به یک میزبان راه دور لاگین می‌شود و فرمان‌ها را در آنجا اجرا می‌کند. این برنامه، پیاده‌سازی امنِ telnet‏، rlogin‏، rcp، و rsh، تصدیق هویت و رمز را به کار می‌برد. برای توضیحات تفصیلی صفحه man آن را ملاحظه نمایید.

مثال ‎16-44‎. کاربرد ssh

#!/bin/bash
# ‎remote.bash:‎  ssh کاربرد

#این مثال نوشته ‎Michael Zick‎ است.
#با مجوز در اینجا استفاده گردیده.


#       فرضیات:
#   ------------
#           توصیف‌گر فایل شماره ‎2‎ ضبط نمی‌شود ‎( '2>/dev/null' )‎.
#‎ssh/sshd‎ فرض می‌کند ‎stderr (2)‎ برای کاربر نمایش داده خواهد شد.
#
# ‎sshd‎ روی ماشین شما در حال اجرا است. برای هر توزیع استاندارد،
#احتمالاً چنین است، بدون اینکه ‎ssh-keygen‎ ناجوری انجام شده باشد.

#    در ماشین خود  ‎ssh‎ را از خط فرمان امتحان کنید، به این صورت:

#   $ ssh $HOSTNAME
#    بدون هرگونه تنظیم اضافی، کلمه عبور از شما پرسیده خواهد شد.
#                                         کلمه‌عبور را وارد کنید
#                     پس از انجام، جهت خروج  exit را وارد کنید.
#
#  آیا کار می‌کند؟ اگر چنین است آماده انجام موارد جالب‌تری هستید.

#   به عنوان کاربر ارشد اجرای ‎ssh‎ را روی ماشین خود امتحان کنید:
#
#     $  ssh -l root $HOSTNAME
#وقتی کلمه عبور پرسیده شد، رمز root را وارد کنید نه رمز خود را.
#Last login: Tue Aug 10 20:25:49 2004 from localhost.localdomain
#                             وقتی انجام شد،  exit را وارد کنید.

#                مورد فوق یک پوسته محاوره‌ای به شما ارایه می‌کند.
#  امکان دارد وضعیت «فرمان منفرد» برای ‎sshd‎ تنظیم شده باشد، اما
#+                        این مطلب خارج از محدوده این مثال است.
#  تنها مورد قابل ذکر کردن آن است که ادامه مثال در وضعیت «فرمان 
#+                                         منفرد» کار خواهد کرد.


#               یک فرمان پایه، نوشتن در خروجی استاندارد (محلی)‏.

ls -l

#                   اکنون همان فرمان پایه روی یک ماشین راه دور.
# اگر مایل هستید، یک ‎'USERNAME'‎ و ‎'HOSTNAME'‎ متفاوت عبور بدهید:
USER=${USERNAME:-$(whoami)}
HOST=${HOSTNAME:-$(hostname)}

#    اکنون سطر فرمان فوق را با ارسال‌های رمزگذاری شده روی میزبان
#+                                        راه دور، اجرا نمایید.

ssh -l ${USER} ${HOST} " ls -l "

#  نتیجه مورد انتظار، لیست‌گیری از دایرکتوری خانگی نام کاربری شما
#+                                         در ماشین راه دور است.
#برای مشاهده هر مورد متفاوتی، این اسکریپت را از جای دیگری غیر از
#+                               دایرکتوری خانگی‌تان اجرا نمایید.

#    به عبارت دیگر، فرمان ‎Bash‎ به صورت یک سطر نقل‌قول‌شده به پوسته
#+  راه دور که آن را روی ماشین راه دور اجرا می‌کند، تحویل می‌گردد.
#   در این حالت، ‎sshd‎ از طرف شما ‎bash -c "ls -l"‎ را انجام می‌دهد.

#برای اطلاعات در باره موضوعاتی از قبیل عدم نیاز به ورود کلمه عبور
#+   یا عبارت عبور برای هر سطر فرمان، موارد زیر را ملاحظه نمایید.
#+    man ssh
#+    man ssh-keygen
#+    man sshd_config.

exit 0

Caution

داخل یک حلقه، ssh ممکن است باعث رفتار غیر منتظره‌ای بشود. مطابق یک یادداشت Usenet در بایگانی‌های ‎‎comp.unix.shell‎‏، ssh ورودی استاندارد حلقه را به ارث می‌برد. برای چاره کردن این مشکل، یکی از گزینه‌های ‎-n‎ یا ‎-f‎ را به ssh بدهید.

تشکر از ‎Jason Bechtel‎ برای روشن کردن این مورد.

scp

‎Secure copy‎‏، در عملکردی مشابه با rcp، فایل‌ها را بین دو ماشین شبکه شده مختلف کپی می‌کند، اما این کار را با استفاده از اعتبار سنجی و یک سطح ایمنی مشابه با ssh انجام می‌دهد.

شبکه محلی


write

این برنامه‌ای برای ارتباطات ترمینال به ترمینال است. فرستادن سطرهایی از ترمینال شما (کنسول یا ‎xterm‎) به ترمینال یک کاربر دیگر را میسر می‌کند. البته فرمان mesg می‌تواند برای غیرفعال کردن دسترسی نوشتن در یک ترمینال به کار برود.

چون write تعاملی است، به طور معمول در یک اسکریپت مورد استفاده پیدا نمی‌کند.

netconfig

یک برنامه سودمند خط فرمانی برای پیکربندی یک تطبیق‌دهنده شبکه (با استفاده از DHCP) است. این فرمان در توزیع‌های لینوکس ‎Red Hat‎ بومی است.

نامه‌رسانی


mail

پیغام‌های ‎e-mail‎ را می‌خواند یا می‌فرستد.

این سرویس‌گیرنده پستی حداقلی خط‌فرمانی، به صورت یک فرمان جاسازی شده در اسکریپت به خوبی کار می‌کند.

مثال ‎16-45‎. اسکریپتی که خودش را پست می‌کند

#!/bin/sh
# ‎self-mailer.sh:‎ اسکریپت فرستنده خود

adr=${1:-`whoami`}   #اگر کاربری مشخص نشود، کاربر جاری پیش‌فرض باشد.
#      با تایپ کردن ‎self-mailer.sh wiseguy@superdupergenius.com‎ این
#+                                اسکریپت به آن آدرس فرستاده می‌شود.
#    تایپ فقط ‎self-mailer.sh‎ (بدون شناسه)، اسکریپت را به شخصی که آن
#+    را احضار نموده، به عنوان مثال برای ‎bozo@localhost.localdomain‎
#   می‌فرستد. برای اطلاعات بیشتر در مورد ساختار ‎${parameter:-default}‎
#+بخش «جایگزینی پارامتر» در فصل «دستکاری متغیرها» را مطالعه نمایید.

# ============================================================================
  cat $0 | mail -s "Script \"`basename $0`\" has mailed itself to you." "$adr"
# ============================================================================

# --------------------------------------------
#          با احترام از اسکریپت ‎self-mailing‎
# یک شخص بدجنس این اسکریپت را اجرا کرده است،
#+که باعث گردیده است خودش را به شما پست کند.
#   ظاهراً، برخی اشخاص کار بهتری برای صرف وقت
#+                            خودشان ندارند.
# --------------------------------------------

echo "At `date`, script \"`basename $0`\" mailed to "$adr"."

exit 0

#توجه کنید که فرمان ‎mailx‎ (در وضعیت ‎send‎) می‌تواند جایگزین
#+         ‎mail‎ بشود، اما با گزینه‌های تا اندازه‌ای متفاوت.

mailto

مشابه با فرمان mail، فرمان mailto پیغام‌های ‎e-mail‎ را از خط‌فرمان یا داخل یک اسکریپت ارسال می‌کند. اما، mailto فرستادن پیغام‌های ‎MIME‎ (چند رسانه‌ای) را نیز اجازه می‌دهد.

mailstats

نمایش آمار mail. این فرمان فقط توسط کاربر ارشد (root) می تواند فراخوانی بشود.

root# mailstats

 Statistics from Tue Jan  1 20:32:08 2008
  M   msgsfr  bytes_from   msgsto    bytes_to  msgsrej msgsdis msgsqur  Mailer
  4     1682      24118K        0          0K        0       0       0  esmtp
  9      212        640K     1894      25131K        0       0       0  local
 =====================================================================
  T     1894      24758K     1894      25131K        0       0       0
  C      414                    0

vacation

این برنامه سودمند به طور خودکار به ‎e-mail‎ها پاسخ می‌دهد که دریافت کننده در حال استراحت است و به طور موقت در دسترس نیست. این روی یک شبکه در پیوستگی با sendmail اجرا می‌گردد، و روی یک حساب ‎dial-up POPmail‎ قابل کاربرد نیست.

یادداشت‌ها

[1]

یک daemon پردازش پس‌زمینه‌ای است که ضمیمه یک نشست ترمینال نیست. Daemonها خدمات تعیین‌شده‌ای را انجام می‌دهند، یا در زمان‌های مشخص شده و یا وقتی به طور صریح بواسطه رویدادهای معینی راه‌اندازی گردند.

کلمه «daemon» در یونانی به معنای شبح است، و پیرامون روشی که daemonهای یونیکس در پشت پرده پرسه می‌زنند و به طور خاموش وظایف انتصابی‌شان را انجام می‌دهند، حتماً چیزی اسرارآمیز، تقریباً خارق‌العاده، وجود دارد.