برنامه استاندارد تهیه بایگانی یونیکس. [1] در ابتدا یک برنامه Tape ARchiving بود، این برنامه به یک بسته همهمنظوره توسعه داده شده، که میتواند تمام حالتهای تهیه بایگانی با تمام انواع دستگاههای هدف، از گردانندههای نوار مغناطیسی تا فایلهای معمولی تا حتی stdout را اداره کند (مثال 3-4 را ببینید). tar گنو برای پذیرفتن فیلترهای متنوع فشردهسازی، به روز رسانی گردیده است، برای مثال: tar czvf archive_name.tar.gz * که به طور بازگشتی تمام فایلهای دایرکتوری کاری جاری ($PWD)به غیر از فایلهای نقطهای را بایگانی و gzip میکند. [2]
برخی گزینههای مفید tar:
-c ایجاد (یک بایگانی جدید)
-x استخراج (فایلها از بایگانی موجود)
-t فهرست کردن (محتویات بایگانی موجود)
--delete حذف (فایلها از بایگانی موجود)
این گزینه روی دستگاههای نوار مغناطیسی عمل نمیکند. |
-r پیوست کردن (فایلها به انتهای یک بایگانی موجود)
-A پیوست (فایلهای tar به بایگانی موجود)
-u به رورسانی بایگانی
-d مقایسه بایگانی با سیستم فایل مشخص شده
--after-date فقط پردازش فایلهایی با نشانه تاریخ بعد از تاریخ تعیین شده
-z gzip کردن بایگانی
(متراکم نمودن یا خارج کردن از حالت فشرده نسبت به گزینه -c یا -x ملحق شده به آن)
-j اجرای bzip2 روی بایگانی
بازیابی دادهها از یک بایگانی tar و gzip شده که معیوب است، میتواند دشوار باشد. موقع بایگانی نمودن فایلهای مهم، چند پشتیبان تهیه کنید. |
برنامه سودمند تهیه بایگانی پوسته. فایلهای متن و/یا باینری در یک بایگانی پوسته، بدون متراکم کردن بهم پیوسته میشوند، و بایگانی حاصله در اصل یک اسکریپت پوسته است، بی کم و کاست با سرآیند #!/bin/sh، شامل تمام فرمانهای استخراج بایگانی لازم، بعلاوه خود فایلها. کاراکترهای باینری غیر قابل چاپ در فایل(های) مقصد، در فایل خروجی shar به کاراکترهای اسکی قابل چاپ تبدیل میشوند. بایگانیهای Shar هنوز در گروههای خبری Usenet حضور دارند، اما در غیر اینمورد shar با tar/gzip تعویض گردیده است. فرمان unshar بایگانیهای shar را به شکل اول در میآورد.
فرمان mailshar یک اسکریپت Bash است که از shar برای بهم پیوست نمودن چندین فایل در یک فایل واحد جهت ارسال با e-mail استفاده میکند. این اسکریپت متراکمسازی و uuencoding را پشتیبانی میکند.
برنامه سودمندی برای ایجاد و دستکاری بایگانیها، اساساً مورد استفاده برای دستکاری بایگانی فایلهای کتابخانهای است.
مدیر بسته Red Hat، یا برنامه سودمند rpm یک بستهبندی برای بایگانیهای باینری یا کد منبع فراهم میکند. این برنامه فرمانهایی را برای نصب و کنترل بی نقصی بستهها ضمیمه میکند.
یک rpm -i package_name.rpm ساده به طور معمول برای نصب یک بسته کفایت مینماید ، هرچند که گزینههای معتبر بسیار بیشتری وجود دارد.
rpm -qf شناسایی میکند که یک فایل از کدام بسته سرچشمه میگیرد. bash$ rpm -qf /bin/ls coreutils-5.2.1-31 |
rpm -qa لیست کاملی از تمام بستههای rpm نصب شده بر روی یک سیستم معین ارایه میکند. یک rpm -qa package_name فقط بسته(های) مطابق با package_name را لیست میکند. bash$ rpm -qa redhat-logos-1.1.3-1 glibc-2.2.4-13 cracklib-2.7-12 dosfstools-2.7-1 gdbm-1.8.0-10 ksymoops-2.4.1-1 mktemp-1.5-11 perl-5.6.0-17 reiserfs-utils-3.x.0j-2 ... bash$ rpm -qa docbook-utils docbook-utils-0.6.9-2 bash$ rpm -qa docbook | grep docbook docbook-dtd31-sgml-1.0-10 docbook-style-dsssl-1.64-3 docbook-dtd30-sgml-1.0-10 docbook-dtd40-sgml-1.0-11 docbook-utils-pdf-0.6.9-2 docbook-dtd41-sgml-1.0-10 docbook-utils-0.6.9-2 |
این فرمان کپی بایگانی اختصاصیشده (copy input and output) این روزها به ندرت دیده میشود، به واسطه tar/gzip مهجور شده است. هنوز موارد استفادهای از قبیل انتقال یک درخت دایرکتوری دارد. با یک اندازه بلوک (برای رونوشتبرداری) تعیین شده مناسب، میتواند به طور قابل تحسینی سریعتر از tar باشد.
مثال 16-30. کاربرد cpio برای انتقال یک درخت دایرکتوری
#!/bin/bash #رونوشت برداری از یک درخت دایرکتوری با استفاده ازcpio. #مزایای استفاده از cpio: #سرعت رونوشت گرفتن. این برنامه با لولهها سریعتر از tar است. #برای رونوشت گرفتن از فایلهای خاص (لولههای با نام، و غیره) که #+ممکن است cp در مورد آنها با اشکال مواجه گردد،بسیار مناسب . ARGS=2 E_BADARGS=65 if [ $# -ne "$ARGS" ] then echo "Usage: `basename $0` source destination" exit $E_BADARGS fi source="$1" destination="$2" ################################################################### find "$source" -depth | cpio -admvp "$destination" # #برای کشف رمز این گزینهها صفحههای info فرمان find و cpio را بخوانید. #کد فوق فقط نسبت به $PWD (دایرکتوری جاری) کار میکند . . . #+نام مسیرهای کامل مشخص میگردند. #################################################################### # # #کدی اضافه کنید که وضعیت خروج ($?) لوله find | cpio را کنترل کند #+و اگر مورد اشتباهی پیش بیاید، پیغام خطای مناسب ارایه نماید. exit $?
این فرمان یک فایل rpm را به یک بایگانی cpio تبدیل میکند.
مثال 16-31. باز کردن بستهبندی یک فایل rpm
#!/bin/bash # : ${1?"Usage: `basename $0` target-file"} #نام فایل rpm باید به عنوان یک شناسه مشخص گردد. TEMPFILE=$$.cpio #فایل موقت با نام منحصر به فرد. #$$ شماره ID پردازش اسکریپت است. rpm2cpio < $1 > $TEMPFILE #بایگانی rpm را به cpio تبدیل میکند. cpio --make-directories -F $TEMPFILE -i #استخراج فایلها از بایگانی cpio rm -f $TEMPFILE #حذف فایل بایگانی cpio exit 0 # # #این کنترلها را اضافه کنید: #(1 فایل مقصد موجود است و #+(2 یک فایل بایگانی rpm است. #اشاره: خروجی فرمان file را تجزیه کنید.
ابزار pax (کوتهنوشت portable archive exchange) تهیه دورهای فایلهای پشتیبان را تسهیل میکند و برای قابلحمل بودن بین انواع گوناگون سیستمهای با طعم یونیکس طراحی شده بود. این ابزار به عنوان جانشینی برای tar و cpio در نظر گرفته شده بود.
pax -wf daily_backup.pax ~/linux-server/files #یک بایگانی از تمام فایلها در دایرکتوری هدف ایجاد میکند. #توجه کنید که برای pax ترتیب گزینهها باید صحیح باشد -- #+pax -fw دارای یک نتیجه کاملاً متفاوت است. pax -f daily_backup.pax #فایلهای بایگانی را فهرست میکند. pax -rf daily_backup.pax ~/bsd-server/files #بازیابی فایلهای پشتیبانگیری شده از #+ماشین لینوکس بر روی یک ماشین BSD.
توجه داشته باشید که pax بسیاری از فرمانهای فشردهسازی و تهیه بایگانی استاندارد را به کار میبرد.
برنامه سودمند استاندارد فشردهسازی گنو/یونیکس، جانشین برنامه مالکانه و نامرغوبتر compress میشود. فرمان خارج کردن از حالت فشرده متناظر آن gunzip است، که معادل gzip -d است.
گزینه -c خروجی gzip را به stdout میفرستد. این گزینه موقع لولهکشی به یک فرمان دیگر مفید است. |
فیلتر zcat یک فایل gzip شده را غیر فشرده میکند و به stdout، به طور محتمل به ورودی یک لوله یا تغییر مسیر میفرستد. این در واقع، یک فرمان cat است که روی فایلهای فشرده (از جمله فایلهای تهیه شده با برنامه قدیمیتر compress) عمل میکند. فرمان zcat معادل با gzip -dc است.
روی برخی سیستمهای تجارتی یونیکس، zcat یک مترادف برای uncompress -c است، و روی فایلهای gzip شده عمل نمیکند. |
همچنین مثال 7-7 را مشاهده نمایید.
یک برنامه سودمند فشردهسازی، معمولاً کارآمدتر (اما آهستهتر) از gzip، بویژه روی فایلهای بزرگ. فرمان متناظر آن برای خارج کردن از حالت فشرده bunzip2 است.
مشابه با فرمان zcat، فرمان bzcat نیز یک فایل bzip2 شده را برای ارسال به stdout غیر فشرده میسازد.
نگارشهای جدیدتر tar برای پشتیبانی از bzip2 تعمیر شدهاند. |
این یک برنامه فشردهسازی قدیمیتر مالکانه است، که در توزیعهای یونیکس تجارتی یافت میشود. برنامه کارآمدتر gzip به طور وسیعی جایگزین آن گردیده است. توزیعهای لینوکس معمولاً به منظور سازشپذیری یک compress تطابقیافته پیوست میکنند، اگر چه gunzip میتواند فایلهای ایجاد شده به وسیله compress را از بایگانی استخراج نماید.
فرمان znew فایلهای compress شده را به فایلهای gzip شده تبدیل میکند. |
یک برنامه دیگر فشردهسازی (squeeze)، فیلتری که فقط روی فهرست کلمههای مرتبشده ASCII عمل میکند. از ترکیب دستوری استاندارد فراخوانی یک فیلتر، یعنی sq < input-file > output-file استفاده میکند. سریع، اما نه به کارایی gzip. فیلتر متناظر آن برای خارج کردن از حالت فشرده، unsq است، مانند sq فراخوانی میشود.
خروجی sq میتواند برای فشردهسازی بیشتر به gzip لولهکشی بشود. |
برنامه ایجاد بایگانی و فشردهسازی چند سکویی سازگار با pkzip.exe در DOS. به نظر میرسد بایگانیهای «zip شده» نسبت به «tarballها» واسطه متداولتری برای تبادل فایل در اینترنت هستند.
این برنامههای سودمند لینوکس اجازه میدهند بایگانیهای فشرده شده توسط برنامههای arc.exe، arj.exe، و rar.exe سیستم DOS را از حالت فشرده خارج نمود.
فشردهسازی با کارایی عالی Lempel-Ziv-Markov. ترکیب دستوری lzma مشابه ترکیب دستوری gzip است. سایت 7-zip دارای اطلاعات بیشتری است.
یک ابزار فشردهسازی با کارایی بالا، سازگار با نگارش lzma، و با یک ترکیب دستوری مشابه با ترکیب دستوری gzip. برای اطلاعات بیشتر، مدخل ویکیپدیای آن را ببینید.
یک برنامه سودمند برای شناسایی نوع فایلها. فرمان file file-name یک مشخصهفایل، از قبیل ascii text یا data برای file-name برگشت میدهد. این فرمان بر حسب توزیع لینوکس/یونیکس، به magic numberهای پیدا شده در /usr/share/magic، /etc/magic، یا /usr/lib/magic، مراجعه میکند.
گزینه -f باعث میشود file در وضعیت دستهای، به منظور خواندن از یک فایل که شامل لیستی از نام فایلها جهت بررسی است، اجرا گردد. گزینه -z موقع استفاده روی یک فایل مقصد فشرده، اقدام به تجزیه و تحلیل نوع فایل غیر فشرده را تحمیل میکند.
bash$ file test.tar.gz test.tar.gz: gzip compressed data, deflated, last modified: Sun Sep 16 13:34:51 2001, os: Unix bash file -z test.tar.gz test.tar.gz: GNU tar archive (gzip compressed data, deflated, last modified: Sun Sep 16 13:34:51 2001, os: Unix)
#پیدا کردن اسکریپتهای sh و Bash در یک دایرکتوری معین: DIRECTORY=/usr/local/bin KEYWORD=Bourne #اسکریپتهای Bourne و Bourne-Again shell file $DIRECTORY/* | fgrep $KEYWORD # # # # # #
مثال 16-32. پاک کردن توضیحها از فایلهای برنامه C
#!/bin/bash # توضیحها (/* COMMENT */) در یک برنامه C را پاک میکند. E_NOARGS=0 E_ARGERROR=66 E_WRONG_FILE_TYPE=67 if [ $# -eq "$E_NOARGS" ] then echo "Usage: `basename $0` C-program-file" >&2 #پیغام خطا به stderr. exit $E_ARGERROR fi #بررسی جهت صحت نوع فایل. type=`file $1 | awk '{ print $2, $3, $4, $5 }'` #file $1 نوع فایل را بازتاب می دهد . . . #سپس awk اولین فیلد، نام فایل، را حذف میکند #سپس نتیجه به متغیر type تخصیص داده میشود. correct_type="C source, ASCII text" if [ "$type" != "$correct_type" ] then echo echo "This script works on C program files only." echo exit $E_WRONG_FILE_TYPE fi #اسکریپت sed تا اندازهای مرموز: # sed ' /^\/\*/d /.*\*\//d ' $1 # #اگر چند ساعت صرف یادگیری مقدمات sed کنید، فهمیدن آن آسان است. #برای عمل کردن اسکریپت در صورتی که کد و توضیح در یک سطر باشند #+افزودن یک سطر به اسکریپت sed لازم است. #این کار به عنوان یک تمرین با اهمیت به خواننده واگذار گردید. #کد فوق همچنین سطرهای غیر توضیح دارای یک */ را حذف میکند . . . #+این نتیجه پسندیدهای نیست. exit 0 # #کد زیر این سطر به علت وجود exit 0 فوق، اجرا نخواهد شد. #Stephane Chazelas جایگزین زیر را پیشنهاد میکند: usage() { echo "Usage: `basename $0` C-program-file" >&2 exit 1 } WEIRD=`echo -n -e '\377'` #یا WEIRD=$'\377' [[ $# -eq 1 ]] || usage case `file "$1"` in *"C program text"*) sed -e "s%/\*%${WEIRD}%g;s%\*/%${WEIRD}%g" "$1" \ | tr '\377\n' '\n\377' \ | sed -ne 'p;n' \ | tr -d '\n' | tr '\377' '\n';; *) usage;; esac #این بازهم توسط مواردی مانند این فریب داده میشود: # # #/* توضیح تعبیه شده اشکالدار */ # #برای اداره تمام موارد خاص (توضیحها در رشتهها، توضیح در #+رشتهای که در آن یک \"، \\" وجود دارد)، تنها راه نوشتن #+یک تجزیهکننده C است (شاید با استفاده از lex یا yacc) exit 0
which command مسیر کامل برای «command» را ارایه میدهد. این برای پیبردن به اینکه آیا یک فرمان یا برنامه سودمند خاص روی سیستم نصب شده است، مفید است.
$bash which rm /usr/bin/rm
برای یک استفاده جالب از این فرمان، مثال 36-16 را ببینید.
مشابه which فوق، whereis command مسیر کامل «command» را ارایه میدهد، اما مسیر کامل صفحه man آن را هم ارایه میکند.
$bash whereis rm rm: /bin/rm /usr/share/man/man1/rm.1.bz2
whatis command فرمان «command» را در بانک اطلاعات whatis جستجو میکند. این فرمان برای شناسایی فرمانهای سیستم و فایلهای پیکربندی مهم، سودمند است. آن را یک فرمان سادهسازی شده man در نظر بگیرید.
$bash whatis whatis whatis (1) - search the whatis database for complete words
مثال 16-33. سیاحت کردن /usr/X11R6/bin
#!/bin/bash #تمام آن باینریهای مرموز در /usr/X11R6/bin چه هستند؟ DIRECTORY="/usr/X11R6/bin" #همچنین /bin، /usr/bin، /usr/local/bin، وغیره را امتحان کنید for file in $DIRECTORY/* do whatis `basename $file` #اطلاعات در باره باینری را منعکس میکند. done exit 0 #توجه:برای اینکه این کد عمل کند، شما باید بانک اطلاعات whatis را با #+/usr/sbin/makewhatis ایجاد نمایید. شاید مایل باشید خروجی اسکریپت #را به این شکل تغییر مسیر بدهید ./what.sh >>whatis.db یا آن را با #دسنور ./what.sh | less به صورت صفحه به صفحه مشاهده نمایید
همچنین مثال 11-3 را مشاهده نمایید.
نمایش یک فهرست دارای جزییات از دایرکتوری. نتیجه آن مشابه با ls -lb است.
این یکی از برنامههای سودمند مدیریت فایل گنو است.
bash$ vdir total 10 -rw-r--r-- 1 bozo bozo 4034 Jul 18 22:04 data1.xrolo -rw-r--r-- 1 bozo bozo 4602 May 25 13:58 data1.xrolo.bak -rw-r--r-- 1 bozo bozo 877 Dec 17 2000 employment.xrolo bash ls -l total 10 -rw-r--r-- 1 bozo bozo 4034 Jul 18 22:04 data1.xrolo -rw-r--r-- 1 bozo bozo 4602 May 25 13:58 data1.xrolo.bak -rw-r--r-- 1 bozo bozo 877 Dec 17 2000 employment.xrolo
فرمان locate فایلها را با استفاده از یک بانک اطلاعات که درست برای همین منظور ذخیره گردیده جستجو میکند. فرمان slocate نگارش ایمن locate (که شاید مستعار slocate شده باشد) است.
bash$ locate hickson /usr/lib/xephem/catalogs/hickson.edb
این فرمانها file access control list (لیست کنترل دسترسی)-- مالک، گروه، و مجوزهای فایل را بازیابی یا تنظیم میکنند.
bash$ getfacl * # file: test1.txt # owner: bozo # group: bozgrp user::rw- group::rw- other::r-- # file: test2.txt # owner: bozo # group: bozgrp user::rw- group::rw- other::r-- bash$ setfacl -m u:bozo:rw yearly_budget.csv bash$ getfacl yearly_budget.csv # file: yearly_budget.csv # owner: accountant # group: budgetgrp user::rw- user:bozo:rw- user:accountant:rw- group::rw- mask::rw- other::r--
فایلی را که یک لینک نمادین به آن اشاره میکند، آشکار میسازد.
bash$ readlink /usr/bin/awk ../../bin/gawk
فرمان strings را برای پیدا کردن رشتههای قابل چاپ در یک فایل دادهای یا باینری، به کار ببرید. این فرمان رشته کاراکترهای قابل چاپ پیدا شده در فایل مقصد را لیست خواهد نمود. این عمل، میتواند برای یک معاینه غیر فنی و سریع از یک فایل رونوشت حافظه (core dump) یا بازرسی یک فایل تصویری ناشناس مفید باشد (strings image-file | more ممکن است چیزی مانند JFIF را نشان بدهد، که فایل را به عنوان یک فایل گرافیکی jpeg معرفی خواهد نمود). در یک اسکریپت، احتمالاً شما خروجی strings را با grep یا sed تجزیه خواهید نمود. مثال 11-8 و مثال 11-10 را نیز مشاهده نمایید.
مثال 16-34. یک فرمان strings «بهبودیافته»
#!/bin/bash # # #این اسکریپت خروجی strings را از طریق کنترل آن در برابر #+یک فایل لیست کلمه استاندارد، فیلتر میکند. #این به طور موثری حروف شکسته و نامفهوم و آلودگی را حذف #+نموده و فقط کلمات شناسایی شده را بیرون میدهد. # # ARGS=1 E_BADARGS=85 E_NOFILE=86 if [ $# -ne $ARGS ] then echo "Usage: `basename $0` filename" exit $E_BADARGS fi if [ ! -f "$1" ] # then echo "File \"$1\" does not exist." exit $E_NOFILE fi # MINSTRLEN=3 # WORDFILE=/usr/share/dict/linux.words # # #+امکانپذیر است، برای مثال بسته لیست کلمه «yawl» از اینجا # wlist=`strings "$1" | tr A-Z a-z | tr '[:space:]' Z | \ tr -cs '[:alpha:]' Z | tr -s '\173-\377' Z | tr Z ' '` #ترجمه کردن خروجی فرمان strings با چند بار عبور دادن از tr #tr A-Z a-z به حروف کوچک تبدیل میکند. #tr '[:space:]' کاراکترهای فضای سفید را به Z تبدیل میکند. #tr -cs '[:alpha:]' Z کاراکترهای غیرالفبایی را به Z تبدیل #+کرده و چند Z متوالی را بهم فشرده مینماید. #tr -s '\173-\377' Z کاراکترهای پس از z #+(م : در ترتیب اسکی) را بهZ تبدیل نموده و Zهای چندگانه متوالی را بهم فشرده میسازد که #+از تمام کاراکترهای عجیب و غریبی که ترجمه قبلی برای رسیدگی #+به آنها موفق نبوده، خلاص میشود. #سرانجام، tr Z ' ' تمام آن Zها را به فضای سفید تبدیل میکند که #+در حلقه زیر به عنوان جداکننده کلمه دیده خواهند شد. # #به تکنیک تغذیه/لولهکشی خروجی tr در برگشت به خودش اما با شناسهها #+و/یا گزینههای متفاوت، در هر عبور متوالی توجه نمایید. # for word in $wlist #مهم: #$wlist نباید نقلقولی باشد. #"$wlist" کار نمیکند. #چرا کار نمیکند؟ do strlen=${#word} #طول رشته. if [ "$strlen" -lt "$MINSTRLEN" ] #ذکر نکردن رشتههای کوتاه. then continue fi grep -Fw $word "$WORDFILE" #فقط انطباق کلمههای کامل. #گزینههای «Fixed strings» و «whole words». done exit $?
diff: برنامه سودمند قابل انعطاف مقایسه فایل. این فرمان فایلهای هدف را سطر به سطر به طور متوالی مقایسه میکند. در برخی کاربردها، از قبیل همسنجی فرهنگهای لغت، ممکن است قبل از لولهکشی آنها به diff فیلتر کردن فایلها از میان sort و uniq کمککننده باشد. diff file-1 file-2 سطرهایی را که در دوفایل تفاوت دارند، با نشانههایی که نشان میدهند هر سطر متعلق به کدام فایل بخصوص است، در خروجی ارایه میکند.
گزینه --side-by-side با diff هر یک از فایلهای مقایسه را سطر به سطر در ستون جداگانه، با سطرهای غیر منطبق نشاندار، در خروجی ارایه میدهد. گزینههای -c و -u نیز تفسیر خروجی فرمان را آسانتر میسازند.
پیشافزایشهای متنوع بسیاری برای فرمان diff وجود دارد، از جمله sdiff، wdiff، xdiff، و mdiff.
یک مورد استفاده رایج برای diff، تولید نمودن فایل تفاوتها جهت استفاده شدن به وسیله patch است. گزینه -e فایلهای مناسب برای اسکریپتهای ed یا ex بیرون میدهد.
patch: برنامه سودمند قابل انعطافِ مدیریت نگارشها. با دادن یک فایل تفاوت که به وسیله diff تولید شده، patch میتواند یک نگارش قبلی از یک بسته را به نگارش جدیدتر ارتقا بدهد. توزیع یک فایل نسبتاً کوچک diff بسیار آسانتر از توزیع پیکر کامل بسته به تازگی تجدید نظر شده است. «patchهای» کرنل شیوه پسندیدهای برای توزیع انتشارهای پیاپی کرنل لینوکس گردیدهاند.
patch -p1 <patch-file #تمام تغییرات فهرست شده در patch-file را اخذ میکند و #آنها را در فایلهای اشاره شده در آنجا اعمال میکند. #این کار بسته را به یک نگارش جدیدتر ارتقا میدهد.
Patch کردن کرنل:
cd /usr/src gzip -cd patchXX.gz | patch -p0 #ارتقا دادن منبع کرنل با استفاده از patch #از «README» مستندات کرنل لینوکس، به وسیله #مولف ناشناس (Alan Cox?).
bash$ diff -r ~/notes1 ~/notes2 Only in /home/bozo/notes1: file02 Only in /home/bozo/notes1: file03 Only in /home/bozo/notes2: file04 |
یک نگارش توسعهیافته از diff که سه فایل را با هم مقایسه میکند. این فرمان با اجرای موفق، یک وضعیت خروج 0 برگشت میدهد، اما متاسفانه اطلاعاتی در باره نتایج مقایسه ارایه نمیدهد.
bash$ diff3 file-1 file-2 file-3 ==== 1:1c This is line 1 of "file-1". 2:1c This is line 1 of "file-2". 3:1c This is line 1 of "file-3"
فرمان merge (ادغام سه طرفه فایل) یک پیوست جالب برای diff3 است. ترکیب دستوری آن merge Mergefile file1 file2 است. نتیجه، نوشتن تغییرات file2 نسبت به file1 در فایل Mergefile است. این فرمان را یک نگارش حداقلی از patch در نظر بگیرید.
مقایسه و/یا ویرایش دو فایل به منظور ادغام آنها در یک فایل خروجی. این فرمان به دلیل طبیعت محاورهایاش، مورد استفاده کمی در یک اسکریپت خواهد داشت.
فرمان cmp نگارش سادهتر diff است. در حالیکه diff تفاوتهای بین دو فایل را گزارش میکند، cmp فقط نشان میدهد که آنها در کدام نقطه تفاوت دارند (
مانند diff، فرمان cmp نیز اگر فایلهای مقایسه شده یکسان باشند، یک وضعیت خروج 0 و در صورت تفاوت آنها یک وضعیت خروج 1 برگشت میدهد. این موضوع، استفاده از آن در یک ساختار بررسی در داخل اسکریپت را میسر میسازد. |
مثال 16-35. کاربرد cmp در داخل یک اسکریپت برای مقایسه دوفایل.
#!/bin/bash # ARGS=2 # E_BADARGS=85 E_UNREADABLE=86 if [ $# -ne "$ARGS" ] then echo "Usage: `basename $0` file1 file2" exit $E_BADARGS fi if [[ ! -r "$1" || ! -r "$2" ]] then echo "Both files to be compared must exist and be readable." exit $E_UNREADABLE fi cmp $1 $2 &> /dev/null #تغییر مسیر به /dev/null خروجی فرمان cmp را مدفون میسازد. #cmp -s $1 $2 دارای همان نتیجه است (-s نشانه silent برای cmp است). #با تشکر از Anders Gustavsson برای توضیح این مورد. # #همچنین با diff هم کار میکند، یعنی به صورت diff $1 $2 &> /dev/null if [ $? -eq 0 ] #بررسی وضعیت خروج فرمان cmp. then echo "File \"$1\" is identical to file \"$2\"." else echo "File \"$1\" differs from file \"$2\"." fi exit 0
برایی فایلهای gzip شده از فرمان zcmp استفاده نمایید. |
برنامه سودمند همهفنحریف مقایسه فایل. برای اینکه این برنامه مفید واقع گردد، فایلها باید مرتبشده باشند.
comm -options first-file second-file
سطر فرمان comm file-1 file-2 سه ستون بیرون میدهد:
ستون 1 = سطرهای منحصر به file-1
ستون 2 = سطرهای منحصر به file-2
ستون 3 = سطرهای مشترک در هر دو فایل.
گزینهها، سرکوب کردن یک یا چند ستون خروجی را میسر میکنند.
-1 بیرون دادن ستون 1 را موقوف میکند
-2 بیرون دادن ستون 2 را موقوف میکند
-3 بیرون دادن ستون 3 را موقوف میکند
-12 بیرون دادن هر دو ستون 1 و 2 را موقوف میکند
این فرمان برای مقایسه «فرهنگ لغتها» یا لیست کلمهها -- فایلهای متن مرتبشده با یک کلمه در هر سطر -- مفید است.
اطلاعات مسیر را از یک نام فایل میزداید، فقط نام فایل را چاپ میکند. ساختار basename $0 اجازه میدهد که اسکریپت، نامش را بداند، یعنی نامی که بواسطه آن فراخوانی گردیده است. این مطلب در صورت لزوم میتواند برای پیغام «نحوه کاربرد» مفید باشد، به طور مثال برای اسکریپتی که بدون شناسههای لازم فراخوانی میشود:
echo "Usage: `basename $0` arg1 arg2 ... argn"
basename را از یک نامفایل میزداید، فقط اطلاعات مسیر را چاپ میکند.
basename و dirname روی هر رشته دلخواه میتوانند عمل کنند. نیازی نیست شناسه به یک فایل موجود اشاره نماید، یا حتی نزدیک به نام یک فایل باشد ( مثال A-7 را ببینید). |
مثال 16-36. basename و dirname
#!/bin/bash address=/home/bozo/daily-journal.txt echo "Basename of /home/bozo/daily-journal.txt = `basename $address`" echo "Dirname of /home/bozo/daily-journal.txt = `dirname $address`" echo echo "My own home is `basename ~/`." #`basename ~` نیز کار میکند. echo "The home of my home is `dirname ~/`." #`dirname ~` نیز کار میکند. exit 0
اینها برنامههای سودمندی برای تفکیک یک فایل به قطعههای کوچکتر هستند. کاربرد متداول آنها، در تقسیم کردن فایلهای بزرگ برای پشتیبانگیری از آنها بر روی فلاپیها یا آمادهسازی جهت e-mail کردن یا upload نمودن آنها است.
فرمان csplit یک فایل را برحسب مضمون تفکیک میکند، تفکیک در جایی رخ میدهد که الگوها منطبق بشوند.
مثال 16-37. اسکریپتی که خودش را به قطعههایی تقسیم میکند
#!/bin/bash # # #+ #+ CHUNKSIZE=4 # OUTPREFIX=xx #csplit به طور پیشفرض فایلها را با #+xx پیشوند میکند ... csplit "$0" "$CHUNKSIZE" #چند سطر توضیح برای پُر کردن بلوک . . . # # # # # # cat "$OUTPREFIX"* > "$0.copy" # rm "$OUTPREFIX"* # exit $?
اینها برنامههای سودمندی برای تولید checksumها هستند. یک checksum عددی [3] است که برای کنترل صحت و سلامت یک فایل، به طور ریاضی از محتوای آن محاسبه گردیده. یک اسکریپت ممکن است برای مقاصد راستیآزمایی از قبیل حصول اطمینان در مورد اینکه محتویات فایلهای کلیدی سیستم تعویض یا خراب نشدهاند، به لیستی از checksumها مراجعه کند. برای برنامههای کاربردی ایمن، از فرمان md5sum (message digest 5 checksum)، یا بازهم مناسبتر، فرمان جدیدتر sha1sum (Secure Hash Algorithm) استفاده کنید. [4]
bash$ cksum /boot/vmlinuz 1670054224 804083 /boot/vmlinuz bash$ echo -n "Top Secret" | cksum 3391003827 10 bash$ md5sum /boot/vmlinuz 0f43eccea8f09e0a0b2b5cf1dcf333ba /boot/vmlinuz bash$ echo -n "Top Secret" | md5sum 8babc97a6f62a4649716f4df8d61728f -
فرمان cksum اندازهای برحسب بایت در مورد مقصدش، خواه فایل یا stdout، نشان میدهد.
فرمانهای md5sum و sha1sum وقتی ورودیشان را از stdout دریافت میکنند یک dash نمایش میدهند. |
#!/bin/bash # E_DIR_NOMATCH=80 E_BAD_DBFILE=81 dbfile=File_record.md5 #نام فایل برای نگهداری رکوردها (فایل بانک اطلاعات). set_up_database () { echo ""$directory"" > "$dbfile" #نوشتن نام دایرکتوری در سطر نخست فایل. md5sum "$directory"/* >> "$dbfile" #درج checksumهای md5 و نام فایلها. } check_database () { local n=0 local filename local checksum # #شاید این کنترل فایل ضروری نباشد، اما احتیاط بهتر از افسوس است. if [ ! -r "$dbfile" ] then echo "Unable to read checksum database file!" exit $E_BAD_DBFILE fi # while read record[n] do directory_checked="${record[0]}" if [ "$directory_checked" != "$directory" ] then echo "Directories do not match up!" #از فایل checksumهابرای یک دایرکتوری متفاوت استفاده شده است. exit $E_DIR_NOMATCH fi if [ "$n" -gt 0 ] #اگر نام دایرکتوری (سطر اول) نیست. then filename[n]=$( echo ${record[$n]} | awk '{ print $2 }' ) #md5sum رکوردها را برعکس مینویسد، اول checksum، سپس نام فایل. checksum[n]=$( md5sum "${filename[n]}" ) if [ "${record[n]}" = "${checksum[n]}" ] then echo "${filename[n]} unchanged." elif [ "`basename ${filename[n]}`" != "$dbfile" ] #از قلم انداختن نام فایل بانک اطلاعات checksum که #+با هر فراخوانی اسکریپت تغییر خواهد کرد. # #متاسفانه این به معنای آن است که در زمان اجرای #+اسکریپت در $PWD، ناخنک زدن به فایل بانک اطلاعات #+checksum تشخیص داده نمیشود. #تمرین: این مشکل را برطرف کنید. then echo "${filename[n]} : CHECKSUM ERROR!" #فایل پس از آخرین باری که کنترل شده، تغییر کرده است. fi fi let "n+=1" done <"$dbfile" #خواندن از فایل بانک اطلاعات checksum. } # # if [ -z "$1" ] then directory="$PWD" #اگر تعیین نشده، استفاده از دایرکتوری جاری else directory="$1" fi clear #پاک کردن صفحه نمایش echo " Running file integrity check on $directory" echo # if [ ! -r "$dbfile" ] #ایجاد فایل بانک اطلاعات لازم است؟ then echo "Setting up database file, \""$directory"/"$dbfile"\"."; echo set_up_database fi # check_database #انجام کار واقعی. echo #شاید مایل باشید خروجی این اسکریپت را به یک فایل تغییر مسیر بدهید، #+مخصوصاً در حالتی که دایرکتوری مورد بررسی دارای فایلهای بسیار باشد. exit 0 #برای یک کنترل بسیار کاملترِ صحت فایل، بسته Tripwire را ملاحظه کنید. #+
همچنین مثال A-19، مثال 36-16، و مثال 10-2 را برای استفاده سازنده از فرمان md5sum مشاهده نماید.
گزارشهایی وجود دارد که md5sum ۱۲۸ بیت میتواند شکسته شود، بنابراین sha1sum ۱۶۰ بیت ایمنتر، یک افزایش جدید خوشایند به جعبه ابزار checksum است.
bash$ md5sum testfile e181e2c8720c60522c4c4c981108e367 testfile bash$ sha1sum testfile 5d7425a9c08a66c3177f1e31286fa40986ffc996 testfile |
مشاوران امنیت به اثبات رساندهاند که حتی sha1sum میتواند در خطر کشف رمز باشد. خوشبختانه، توزیعهای جدیدتر لینوکس فرمانهای sha224sum، sha256sum، sha384sum، و sha512sum با بیتهای بیشتر را پیوست میکنند.
این برنامه سودمند، فایلهای باینری (تصویرها، فایلهای صوتی، فایلهای فشرده، و غیره) را جهت مناسب نمودن آنها برای انتقال در بدنه پیغامهای e-mail یا پست کردن در یک گروه خبری، به کاراکترهای ASCII کدگذاری میکند. این مخصوصاً در جایی که کدگذاری MIME (multimedia) معتبر نیست، سودمند است.
این فرمان برعکس کدگذاری، فایلهای uuencod شده را از کد خارج و به باینریهای اصلی برمیگرداند.
مثال 16-39. Uudecod کردن فایلهای encod شده
#!/bin/bash #تمام فایلهای uuencod شده در دایرکتوری کاری جاری را uudecod میکند. lines=35 #برای سرآیند 35 سطر اجازه میدهد (بسیار سخاوتمندانه). for File in * #بررسی تمام فایلها در $PWD. do search1=`head -n $lines $File | grep begin | wc -w` search2=`tail -n $lines $File | grep end | wc -w` #فایلهای uuencod شده دارای یک "begin" تقریباً در ابتدا #و یک "end" در نزدیکی انتهایشان هستند. if [ "$search1" -gt 0 ] then if [ "$search2" -gt 0 ] then echo "uudecoding - $File -" uudecode $File fi fi done #توجه نمایید که اجرای این اسکریپت روی خودش، آن را به طرف #+تصور آنکه یک فایل uuencod شده است، فریب میدهد زیرا شامل #+هر دو کلمه "begin" و "end" است. #تمرین: # #این اسکریپت را جهت کنترل هر فایل برای سرآیند گروه خبری #+و رفتن به مورد بعدی در صورت نیافتن آن، ویرایش نمایید. exit 0
فرمان fold -s ممکن است برای پردازش پیغامهای متن طولانی دانلود شده از گروههای خبری Usenet سودمند باشد (احتمالاً در یک لوله). |
فرمانهای mimencode و mmencode پیوستهای پیغام e-mail با کدگذاری MIME را پردازش میکنند. اگرچه کارگزار های نامهرسان کاربر (از قبیل pine یا kmail) معمولاً به طور خودکار این مورد را اداره میکنند، اما این برنامههای خاص، از طریق خط فرمان یا در وضعیت پردازش دستهای به وسیله یک اسکریپت پوسته، کار کردن با چنین پیوستهایی را میسر میسازند.
زمانی، این برنامه استاندارد رمزنگاری فایل در یونیکس بود. [5] مقررات دولتی برانگیخته از مقاصد سیاسی، با ممنوعیت صدور نرمافزار رمزنگاری، منجر به ناپدید شدن crypt در بخش زیادی از جهان یونیکس گردید، و هنوز هم در اکثر توزیعهای لینوکس غایب است. خوشبختانه، برنامهنویسان تعدادی جایگزین شایسته برای آن اندیشیده و ارایه نمودهاند، از جمله cruft که متعلق به خود نگارنده است ( مثال A-4 را ببینید).
این یک پیادهسازی منبعباز رمزنگاری Secure Sockets Layer است.
#برای رمزی کردن یک فایل: openssl aes-128-ecb -salt -in file.txt -out file.encrypted \ -pass pass:my_password # # #برای رمزگشایی یک فایل رمزیشده openssl: openssl aes-128-ecb -d -salt -in file.encrypted -out file.txt \ -pass pass:my_password #
لولهکشی openssl به/از tar رمزی کردن یک درخت دایرکتوری کامل را ممکن میسازد.
#برای رمزی کردن دایرکتوری: sourcedir="/home/bozo/testfiles" encrfile="encr-dir.tar.gz" password=my_secret_password tar czvf - "$sourcedir" | openssl des3 -salt -out "$encrfile" -pass pass:"$password" # #فایل رمزیشده encr-dir.tar.gz را در دایرکتوری کاری جاری مینویسد. #برای رمزگشایی فایل tarball حاصله: openssl des3 -d -salt -in "$encrfile" -pass pass:"$password" | tar -xzv #رمزگشایی نموده و در دایرکتوری کاری جاری از بستهبندی خارج میکند.
البته، openssl استفادههای بسیار دیگری دارد، از جمله فراهم کردن گواهینامههای امضا شده برای پایگاههای وب. صفحه info را ببینید.
پاک کردن یک فایل به طور امن از طریق چندین بار بازنویسی آن با الگوهای تصادفی بیتها، قبل از حذف فایل. این فرمان دارای همان عملکرد مثال 16-61 است، اما آن کار را با یک حالت برازنده و کاملتر انجام میدهد.
این یکی از برنامههای مدیریت فایل گنو است.
ممکن است تکنولوژی پیشرفته دادگاهی، حتی بعد از به کار بردن shred، باز هم قادر به برگرداندن محتویات فایل باشد. |
ایجاد یک فایل موقتی [6] با یک نامفایل «منحصر به فرد». موقعی که از خط فرمان بدون شناسههای اضافی احضار میگردد، فایلی به اندازه صفر بایت در دایرکتوری /tmp ایجاد میکند.
bash$ mktemp /tmp/tmp.zzsvql3154
PREFIX=filename tempfile=`mktemp $PREFIX.XXXXXX` # #+در الگوی نام فایل لازم است. #اگر قالب نامفایل فراهم نشود، tmp.XXXXXXXXXX پیشفرض است. echo "tempfile name = $tempfile" #tempfile name = filename.QA2ZpY یا چیزی مشابه آن. #فایلی با آن نام، بامجوزهای برابر با 600 در دایرکتوری #+کاری جاری تولید میکند. #بنابراین یک umask 177 لازم نیست، اما با این وجود این یک #+عادت پسندیده برنامهنویسی است.
برنامه سودمندی برای build و compile کردن بستهها. این فرمان همچنین میتواند برای هر مجموعه عملیات معلول تغییرات توسعهای فایلهای منبع، به کار برود.
فرمان make به یک Makefile که شامل لیستی از وابستگیهای فایل و عملیاتی است که باید انجام شوند، رسیدگی میکند.
برنامه make عملاً یک زبان اسکریپتنویسی قدرتمند با شباهتهای بسیار به Bash است، اما با توانایی تشخیص وابستگیها. برای یک پوشش عمقی از این مجموعه ابزار مفید، سایت مستندات نرمافزار گنو را مشاهده کنید.
فرمان کپی تک منظوره، مشابه با cp، اما قادر به تنظیم کردن مجوزها و خصوصیات فایلهای کپی شده است. به نظر میرسد این فرمان به طور سفارشی برای نصب بستههای نرمافزاری ساخته شده است، و اغلب در Makefileها (در بخش make install :) حضور دارد. همچنین، میتواند در اسکریپتهای نصب مفید واقع شود.
این برنامه، نوشته شده توسط Benjamin Lin و همکاران، فایلهای متن با قالب DOS (سطرهای خاتمه یافته با CR-LF) را به قالب یونیکس (سطرهای خاتمه یافته با فقط LF) تبدیل میکند و بالعکس.
فرمان ptx [targetfile] یک ایندکس (فهرست ارجاع) جابجا شده از targetfile بیرون میدهد. در صورت لزوم این فهرست بعداً میتواند در یک لوله فیلتر شده و قالببندی بشود.
صفحهبندهایی که یک فایل متن یا جریان stdout را به صورت صفحه به صفحه(در هر نوبت یک صفحه نمایش کامل)، نمایش میدهند. این فرمانها میتوانند برای فیلتر کردن خروجی stdout . . . یا یک اسکریپت به کار بروند.
یک کاربرد جالب فرمان more عبارت است از: «اجرای آزمایشی» یک رشته فرمان جهت پیشدستی بر نتایج ناخوشایند بالقوه موجود.
ls /home/bozo | awk '{print "rm -rf " $1}' | more # #بررسی اجرا کردنِ سطر فرمان (مصیبتبار) پایین: # #
صفحهبند less دارای خصوصیت جالب نمایش صفحهها همانند صفحه man است. مثال A-39 را مشاهده کنید.
[1] | یک بایگانی، در مفهومی که در اینجا مطرح میشود، فقط مجموعهای از فایلهای مرتبط نگهداری شده در یک محل واحد است. |
[2] | یک سطر فرمان tar czvf ArchiveName.tar.gz * فایلهای نقطهای در دایرکتوریهای فرعی تحت دایرکتوری کاری جاری را ضمیمه خواهد نمود. این یک «ویژگی» مستندسازی نشده tar گنو است. |
[3] | checksum شاید به صورت یک شماره هگزادسیمال، یا به برخی مبناهای عددی دیگر بیان بشود. |
[4] | حتی برای امنیت بهتر از این، فرمانهای sha256sum، sha512، و sha1pass را استفاده کنید. |
[5] | بر خلاف کلاس رمزنگاری public key، که pgp مثال شناختهشدهای از آن است، این یک رمز گذاری بلوکی متقارن است که برای رمزنگاری فایلها روی یک سیستم منفرد یا شبکه محلی استفاده میشود. |
[6] | وقتی با گزینه -d فراخوانی شود یک دایرکتوری موقتی ایجاد میکند |