h yavlyayutsya nastoyashchimi komandami sistemy UNIX, peredelannymi v kornevye shell-interpretatory, kotorye zatem pereustanavlivayutsya vmesto pervonachal'nyh shell-interpretatorov. Edinstvennyj nadezhnyj sposob identificirovat' etot poslednij tip - zapustit' pobajtovoe sravnenie mezhdu vashej distributivnoj kopiej ko- mandy sistemy UNIX i toj versiej, kotoraya prisutstvuet v nastoyashchij moment v vashej sisteme. Konechno, pered tem kak vy smozhete proverit' fajly so vklyuchennymi bitami razresheniya ustanovki pol'zovatel'skogo/gruppovogo identifika- tora, vam nuzhno najti vse takie fajly. V sisteme UNIX eto delayut dve komandy: find(1) i ncheck(1M). Utilita find ishchet fajly po nashej toch- noj specifikacii i mozhet byt' ispol'zovana dlya poiska fajlov s zadan- nym naborom prav dostupa, vklyuchaya bity ustanovki identifikatorov. Ncheck pechataet vperemeshku special'nye fajly i fajly s razreshennoj ustanovkoj identifikatora pol'zovatelya. |to ochen' bol'shoj spisok, chtenie i poisk v nem interesuyushchih nas fajlov zanimaet mnogo vremeni. Takim obrazom, polezno sozdat' komandnyj fajl, predostavlyayushchij nam vsyu neobhodimuyu informaciyu i tol'ko takuyu informaciyu. Chkset ispol'- zuet komandu find i ishchet tol'ko fajly so vklyuchennymi bitami razreshe- niya ustanovki pol'zovatel'skogo/gruppovogo identifikatora, tak chto rezul'tat soderzhit lish' neobhodimuyu nam informaciyu, i etim rezul'ta- tom mozhno srazu zhe vospol'zovat'sya. CHTO DELAET chkset? Chkset imeet dva rezhima funkcionirovaniya: odin dlya skanirovaniya vsej sistemy v celom, a drugoj dlya skanirovaniya ukazannyh derev'ev katalogov. |to horoshee svojstvo, tak kak skanirovanie kazhdogo fajla sistemy zanimaet ochen' mnogo vremeni. Esli imeetsya mnogo bol'shih dis- kovyh ustrojstv, proverka vsego soderzhimogo sistemy mozhet zanyat' ce- lyj chas. Utilita chkset takzhe ochen' sil'no zagruzhaet central'nyj pro- cessor iz-za vseh processov, kotorye ona generiruet. Ukazyvaya imena katalogov, vy mozhete vypolnit' proverku lish' na opredelennoj oblasti sistemnogo dereva. Otmetim, odnako, chto poskol'ku chkset pol'zuetsya komandoj find, ona skaniruet ne tol'ko ukazannyj vami katalog, no i VSE podchinennye katalogi. Zametim takzhe, chto chkset obnaruzhivaet VSE fajly s ustanovlennymi v edinicu bitami ustanovki pol'zovatel'sko- go/gruppovogo identifikatora, a ne tol'ko te, vladel'cem kotoryh yav- lyaetsya superpol'zovatel' (root). Rezul'tat raboty chkset mozhno vydat' takzhe dvumya sposobami. Esli ne primenyat' nikakuyu opciyu, to forma vydachi rezul'tata opredelyaetsya komandoj "find ... -print", chto oznachaet polnye marshrutnye imena naj- dennyh fajlov. Zatem eti polnye imena sortiruyutsya. Esli primenyaetsya opciya -l, to dlya formatirovaniya rezul'tata is- pol'zuetsya komanda "ls -ld", porozhdayushchaya dlinnyj format listinga. Pri etom raspechatyvayutsya polnoe ukazanie prav dostupa, chislo svyazej, vla- delec, razmer i imya fajla. |tot rezul'tat takzhe sortiruetsya po ime- nam. Vybirajte tot ili inoj format v zavisimosti ot obstoyatel'stv. Esli vam nuzhno proverit' bol'shoj uchastok sistemy i poluchit' spisok podozritel'nyh fajlov, primenite listing po umolchaniyu (bez opcij), tak kak on kompaktnee i, kak my uvidim pozdnee, zanimaet znachitel'no men'she processornogo vremeni. Esli vy hotite zanyat'sya opredelennym katalogom i posmotret' na ego fajly podrobno, vospol'zujtes' opciej - l. Ona predostavlyaet bol'she informacii i izbavlyaet ot neobhodimosti vruchnuyu nabirat' komandy ls dlya interesuyushchih vas fajlov. Otmetim, chto etu komandu mozhet zapustit' kto ugodno, a ne tol'ko administrator, imeyushchij privilegii superpol'zovatelya. Odnako, esli ona zapuskaetsya obychnym pol'zovatelem, to komanda find vnutri komandnogo fajla chkset ogranichena temi fajlami, k kotorym pol'zovatel' imeet dostup na chtenie. Tak chto vy mogli by predlozhit' bolee privilegiro- vannym pol'zovatelyam zapuskat' chkset v kachestve odnoj iz ih lichnyh mer bezopasnosti. Razumeetsya, esli chkset zapuskaetsya superpol'zova- telem, to ogranicheniya prav dostupa k fajlam nesushchestvenny i mozhno podvergnut' proverke vse fajly. PRIMER # chkset /bin /usr/bin /lib /usr/lib |ta komanda vyzyvaet prosmotr ukazannyh katalogov. V katalogah tipa /usr/lib prosmatrivayutsya vse podchinennye katalogi, chto obespechi- vaet bolee tshchatel'nuyu proverku. POYASNENIYA Pervym delom chkset inicializiruet dve peremennye - FORM i SORT. Peremennaya FORM soderzhit komandu dlya vydachi rezul'tata raboty komandy find, a peremennaya SORT - komandu, opredelyayushchuyu, chto nuzhno sortiro- vat'. V stroke 7 proveryaetsya, yavlyaetsya li pervyj pozicionnyj parametr opciej. Esli da, to operator case (stroki 8-14) smotrit, kakaya eto opciya. Esli eto opciya "-l", to podgotavlivaetsya komanda dlya raspechat- ki rezul'tata (eto my obsudim pozzhe). Komanda dlya utility sort formi- ruetsya tak, chtoby sortirovka shla po polyu vladel'ca. Opciya ubiraetsya iz komandnoj stroki, potomu chto vse posleduyushchie argumenty dolzhny byt' katalogami i my zahotim poluchit' k nim dostup s pomoshch'yu "$#". Esli popalas' opciya, otlichnaya ot "-l", to eto oshibka, vydaetsya soobshchenie ob oshibke (stroka 12), i komandnyj fajl zavershaetsya. Esli ostalos' bolee nulya argumentov, kogda my popadaem v stroku 17, to oni proveryayutsya v cikle, chtoby ubedit'sya, chto vse oni yavlyayutsya katalogami. Esli eto ne katalogi, na standartnoe ustrojstvo registra- cii oshibok vydaetsya soobshchenie ob oshibke i komandnyj fajl zavershaetsya. Esli imeyutsya parametry (t.e. katalogi), to v stroke 18 v pere- mennuyu SRC zanosyatsya vse katalogi. Esli zhe parametrov net, to v pere- mennuyu SRC zanositsya znachenie "/", t.e. kornevoj katalog, chtoby obes- pechit' podrazumevaemuyu startovuyu tochku dlya poiska. Vsya rabota etogo komandnogo fajla vypolnyaetsya fakticheski v ope- ratore find. Komanda find dopuskaet mnozhestvennoe ukazanie katalogov, kotorye postupayut v rezul'tate chteniya ih iz komandnoj stroki i zane- seniya v peremennuyu SRC. Posle togo kak my ukazali komande find, otkuda nachinat' poisk, my ukazyvaem ej, chto nuzhno iskat'. V dannom sluchae nas interesuyut vse fajly, kotorye imeyut vklyuchennyj bit ustanovki pol'zovatel'skogo libo gruppovogo identifikatora. My ob®yasnyaem eto komande find putem ukaza- niya prav dostupa, kotorye trebuetsya iskat'. Stroka "-perm -4000" oz- nachaet poisk vseh fajlov, imeyushchih prava dostupa so vklyuchennym bitom ustanovki pol'zovatel'skogo identifikatora i s lyubymi drugimi vklyu- chennymi bitami. Vy mozhete ponimat' etu zapis' kak primenenie simvolov -zamenitelej - 4???. My ishchem kak ustanovku pol'zovatel'skogo identi- fikatora (-4000), tak i ustanovku gruppovogo identifikatora (-2000), poetomu dve stroki prav dostupa soedineny opciej -o, oznachayushchej "or" ("ili"). (Bolee polnoe opisanie prav dostupa v simvolicheskoj i vos'- merichnoj forme privedeno v chmod(1).) Sleduyushchaya zadacha - dobavit' stroku, hranimuyu v peremennoj FORM, v komandnuyu stroku. Esli opciya -l ne byla ispol'zovana, to v peremen- noj FORM hranitsya stroka "-print", a eto znachit, chto find budet pecha- tat' marshrutnye imena najdennyh fajlov. Esli zhe -l ispol'zovalas', to peremennaya FORM soderzhit stroku "-exec ls -ld {} ;". Opciya -exec - eto ochen' gibkaya opciya komandy find, pozvolyayushchaya primenit' lyubye ko- mandy, kotorye za nej sleduyut, k kazhdomu najdennomu fajlu. V dannom sluchae eti komandy vypolnyayut raspechatku v dlinnom formate (-l), pri- chem dlya kazhdogo kataloga (-d) vyvoditsya tol'ko ego imya (a ne soderzhi- moe). Imenno zdes' proishodyat naibol'shie zatraty resursov central'no- go processora, tak kak dlya opcii -l trebuetsya sistemnyj vyzov stat. Iz-za togo, chto dlya kazhdogo fajla trebuetsya komanda ls, ona kazhdyj raz zagruzhaetsya v pamyat' i vypolnyaetsya. Proizvoditsya takzhe dostup k indeksnomu deskriptoru fajla na diske. |to privodit k bol'shim naklad- nym rashodam. Zatem ves' potok dannyh propuskaetsya cherez utilitu sort. Na sa- mom dele my hotim sdelat' sortirovku po vos'momu polyu (vy mozhete pro- verit' eto, vypolniv komandu "ls -l" i izuchiv ee rezul'tat). Utilita sort PROPUSKAET ukazannoe chislo polej, nachinaya s polya 1, yavlyayushchegosya po umolchaniyu startovoj tochkoj, poetomu ispol'zovanie zapisi +7 ozna- chaet perehod k vos'momu polyu, kotorym yavlyaetsya imya fajla. ALXTERNATIVNYJ PODHOD Dlya poiska fajlov s interesuyushchimi nas pravami dostupa mozhno pri- menit' drugoj metod, hotya i bolee medlennyj. On osnovyvaetsya na tom, chto vmesto poiska prav dostupa po chislu, mozhno iskat' ih po simvol'- noj stroke. Dlya etogo nuzhno primenyat' grep. Al'ternativnaya komanda vyglyadit tak: # find $* -exec ls -ld {} \; | grep "^[^ ]*s[^ ]*" |tot variant komandy rabotaet neskol'ko inache. On nahodit kazhdyj fajl iz ukazannyh katalogov i primenyaet k kazhdomu iz nih komandu "ls -ld". Zatem ves' spisok dannyh peredaetsya po konvejeru komande grep. Grep ispol'zuet dlya raspoznavaniya interesuyushchih nas fajlov takoj shab- lon poiska: nachinaya s nachala stroki, najti povtoryayushchijsya simvol, ot- lichnyj ot probela, zatem simvol "s", za kotorym sleduet povtoryayushchijsya simvol, otlichnyj ot probela. Takomu shablonu sootvetstvuyut vse rezhimy prav dostupa, soderzhashchie s, bud' to bit ustanovki pol'zovatel'skogo identifikatora ili bit ustanovki gruppovogo identifikatora. Ne su- shchestvenno, vhodyat li v dannyj rezhim "r", "w", "x" ili "-". Ubediv- shis', chto probelov net, my obespechivaem sootvetstvie shablona tol'ko polyu prav dostupa. Vazhno, chtoby posle s sledovali simvoly, otlichnye ot probelov, tak kak s mozhet vstretit'sya libo v porcii prav dostupa, otnosyashchejsya k vladel'cu, libo v gruppovoj porcii i nigde bol'she. My ne ochen' rekomenduem etot metod, poskol'ku on privlekaet ochen' intensivnuyu obrabotku. Odnako, esli by my ne isprobovali etot metod pervym, my by ne ocenili, chto ispol'zovanie komandy find so strokami "-perm" yavlyaetsya bolee predpochtitel'nym. V silu neveroyatnoj gibkosti sistemy UNIX, imeetsya ochen' mnogo razlichnyh sposobov vypol- neniya odnoj i toj zhe raboty, i mnogie iz etih sposobov mogut davat' odinakovo horoshie rezul'taty, no za raznuyu cenu v smysle bystrodejs- tviya i processornyh zatrat. Pered tem kak primenyat' universal'nuyu utilitu vrode grep dlya resheniya zadachi, rassmotrite, net li drugoj ko- mandy so vstroennoj opciej raspoznavaniya po shablonu. Skoree vsego, primenenie takoj komandy okazhetsya optimal'nee i gorazdo bystree, chem ispol'zovanie grep. S drugoj storony, inogda vam nuzhno bystro reshit' nechasto vstrechayushchuyusya zadachu, ne slishkom zabotyas' ob effektivnosti resheniya. -------------------------------------------------------- IMYA: suw -------------------------------------------------------- suw NAZNACHENIE Prosmatrivaet protokol'nyj fajl komandy su i pechataet imena vseh pol'zovatelej, kotorye nelegal'no prevratilis' v superpol'zovatelya pri pomoshchi komandy su (substituted user, zamenennyj pol'zovatel'). FORMAT VYZOVA suw [-m] [sulog] PRIMER VYZOVA suw Zapusk v rezhime po umolchaniyu, proverka fajla /usr/adm/sulog i vydacha zapisej o narushitelyah v standartnyj vyvod. TEKST PROGRAMMY 1 static char id[]="@(#)suw v1.0 Author: Russ Sage"; 3 # include 5 # define FALSE 0 6 # define TRUE 1 7 # define MATCH 0 8 # define BSIZ 80 10 main(argc,argv) 11 int argc; 12 char *argv[]; 13 { 14 register int alert, c, mail, n; 15 FILE *fp1, *fp2; 16 char *p, *uname, line[BSIZ], tmp[BSIZ], 17 *log = "/usr/adm/sulog"; 19 static char *legal[] = {sage-root\n","root-root\n",NULL}; 20 static char *adm[] = {"sage",NULL}; 23 mail = FALSE; 25 if (argc > 1 && argv[1][0] == '-') 26 switch (argv[1][1]) 27 { 28 case 'm': 29 mail = TRUE; 30 --argc; 31 ++argv; 32 break; 33 default: 34 fprintf(stderr,"suw: invalid argument %s\n", argv[1]); 35 fprintf(stderr,"usage: suw [-m] [sulog]\n"); 36 exit(1); 37 } 39 if (argc == 2) 40 log = *++argv; 42 if ((fp1 = fopen(log,"r")) == NULL) 43 { 44 fprintf(stderr,"suw: error opening %s\n",log); 45 fprintf(stderr,"usage: suw [-m] [sulog]\n"); 46 exit(1); 47 } 49 sprintf(tmp,"/tmp/suw%d",getpid()); 50 if ((fp2 = fopen(tmp,"w+")) == NULL) 51 { 52 fprintf(stderr,"suw: error opening %s\n",tmp); 53 fprintf(stderr,"usage: suw [-m] [sulog]\n"); 54 exit(1); 55 } 57 while (fgets(line,sizeof(line),fp1) != NULL) 58 { 59 p = line + 15; 60 if (*p == '+') 61 { 62 p = p + 2; 63 while (*p != ' ') p++; 64 p++; 65 uname = p; 66 while (*p && *p++ != '-') 67 continue; 69 if (strcmp (p,"root\n") == MATCH) 70 { 71 alert = TRUE; 72 for (n=0; legal[n] != NULL; n++) 73 if (strcmp (uname,legal[n]) == MATCH) 74 { 75 alert = FALSE; 76 break; 77 } 78 if (alert) 79 fprintf(fp2,"Illegal --> %s", line); 80 } 81 } 82 } 84 if (mail) 85 { 86 fclose(fp2); 87 for (n=0; adm[n] != NULL; n++) 88 { 89 sprintf(line,"cat %s | mail %s",tmp,adm[n]); 90 system(line); 91 } 92 } 93 else 94 { 95 rewind(fp2); 96 while ((c = getc(fp2)) != EOF) 97 putc(c, stdout); 98 fclose(fp2); 99 } 101 fclose(fp1); 102 unlink(tmp); 103 } OPISANIE ZACHEM NAM NUZHNA PROGRAMMA suw? Vy pomnite, chto komanda su, pozvolyayushchaya pol'zovatelyam izmenyat' svoyu individual'nost' (i prava dostupa) mozhet byt' istochnikom problem bezopasnosti. Sistema hranit protokol vseh tranzakcij su v fajle sulog. Hotya bolee opytnye narushiteli mogut umet' zatirat' svoi sledy, fajl sulog polezen dlya otslezhivaniya potencial'nyh lazeek v sisteme zashchity. |tim sposobom mozhno pojmat' mnogih narushitelej-lyubitelej. Es- testvenno, my hotim avtomatizirovat' etot process, chtoby sistema vy- polnyala proverku i signalizirovala nam pri obnaruzhenii chego-libo opasnogo. Krome togo, dannaya programma demonstriruet metodiku, koto- ruyu mozhno ispol'zovat' dlya otslezhivaniya drugih protokol'nyh fajlov. CHTO DELAET suw? Programma suw chitaet i analiziruet protokol'nye fajly komandy su. Kazhdoe uspeshnoe prevrashchenie v superpol'zovatelya pri pomoshchi koman- dy su, obnaruzhennoe v protokol'nom fajle, sveryaetsya so spiskom razre- shennyh superpol'zovatelej. Esli pol'zovatelyu ne razresheno byt' super- pol'zovatelem, to konkretnaya zapis' o nem pechataetsya, chtoby opovestit' administratora. Po umolchaniyu zapisi o narushitelyah pechatayutsya v standartnyj vy- vod. Protokol'nym fajlom po umolchaniyu yavlyaetsya /usr/adm/sulog. Esli primenyaetsya opciya -m, to zapisi o narushitelyah rassylayutsya po pochte administratoram, zanesennym v predopredelennyj spisok. Esli nuzhno proverit' drugoj protokol'nyj fajl, naprimer /usr/adm/Osulog, to ego imya mozhno ukazat' v komandnoj stroke. PRIMERY 1. # suw -m Proverit' fajl /usr/adm/sulog i razoslat' zapisi o narushitelyah administratoram, opredelennym v tekste programmy. 2. # suw /usr/adm/Osulog Proverit' fajl /usr/adm/Osulog i napechatat' zapisi o narushitelyah v standartnyj vyvod. POYASNENIYA V samom nachale programmy opredelyayutsya i inicializiruyutsya vse pe- remennye i spiski. V stroke 14 opredeleny dva flaga: alert (signal trevogi) i mail (pochta). Oni imeyut znachenie TRUE ili FALSE. V etoj programme ispol'zuyutsya dva fajla: protokol'nyj fajl komandy su, koto- ryj vy vybiraete, i vremennyj fajl. Poskol'ku my sobiraemsya primenyat' nekotorye podprogrammy standartnogo vvoda-vyvoda (stdio), my pol'zu- emsya ukazatelyami na fajly fp1 i fp2, a ne deskriptorami fajlov. Pri- menyaetsya dva bufera: odin dlya zachityvaniya v nego dannyh iz protokol'- nogo fajla komandy su, a drugoj - dlya hraneniya imeni vremennogo fajla. Pervonachal'no imenem protokol'nogo fajla yavlyaetsya sulog. Esli vmesto nego ispol'zuetsya drugoe imya fajla, to peremennaya log pereus- tanavlivaetsya na eto imya. Zatem inicializiruyutsya predopredelennye spiski razreshennyh su- perpol'zovatelej i administratorov. V nashem primere dvumya razreshenny- mi superpol'zovatelyami yavlyayutsya sage (sage-root) i root (root-root). Dlya togo chtoby prisposobit' eto dlya vashej sistemy, pomestite zdes' imena lyudej, kotorym vy hotite razreshit' pol'zovat'sya komandoj su dlya prevrashcheniya v superpol'zovatelej. Spisok administratorov takzhe dolzhen soderzhat' sootvetstvuyushchie imena. V dannom primere v spisok administ- ratorov vhodit odno imya - sage. |to znachit, chto sage budet edinstven- nym, kto poluchit pochtu, esli ukazana pochtovaya opciya. Podrazumevaemoe sostoyanie rassylki pochty ustanavlivaetsya v stro- ke 23 na znachenie FALSE, t. e. pochty net. |to delaetsya dlya togo, chto- by posle razbora komandnoj stroki peremennaya mail imela pravil'noe znachenie. Dalee vypolnyaetsya proverka na oshibki. Pervaya proverka vyglyadit neskol'ko strannoj, no na samom dele vpolne ponyatna. Peremennaya argc vozvrashchaet chislo argumentov komandnoj stroki, a argv ukazyvaet na massiv, soderzhashchij sami argumenty, kazhdyj iz kotoryh sam yavlyaetsya massivom simvolov. Esli komandnaya stroka voobshche imeet kakie-libo ar- gumenty (argc > 1) i pervym simvolom pervogo argumenta (argv[1][0]) yavlyaetsya defis, to proveryaetsya, korrektnaya li eto opciya. S cel'yu pro- verki vtorogo simvola pervogo argumenta ispol'zuetsya operator case. Esli argumentom yavlyaetsya simvol m, to flag mail ustanavlivaetsya v sostoyanie TRUE, chislo argumentov (argc) umen'shaetsya na edinicu, a ukazatel' na massiv argumentov (argv) na edinicu uvelichivaetsya. |to sluzhit toj zhe celi, chto i udalenie argumentov iz komandnoj stroki v komandnyh fajlah interpretatora shell. Napomnim, chto argv yavlyaetsya v dejstvitel'nosti massivom ukazatelej, a massivy traktuyutsya tochno tak zhe, kak stroki, s bazovym adresom i smeshcheniem. Poetomu argv[0] == argv, i argv[1] == ++argv. Esli opciya otlichaetsya ot -m, to v stan- dartnyj vyvod pechataetsya soobshchenie ob oshibke i programma zavershaetsya. V stroke 39 proveryaetsya schetchik argumentov, chtoby ponyat', est' li eshche odin argument. Napomnim, chto argv vsegda na edinicu otstaet ot argc, potomu chto samo imya komandy yavlyaetsya pervym argumentom massiva. Sledovatel'no, dlya togo chtoby poluchit' vtoroj argument, my dolzhny pe- rejti k sleduyushchej pozicii (*++argv). Esli argument imeetsya, on dolzhen byt' imenem protokol'nogo fajla, i eto imya zanositsya v peremennuyu log. Dalee my pytaemsya otkryt' fajly, ispol'zuemye v programme. Sna- chala otkryvaetsya dlya chteniya protokol'nyj fajl. Esli eto ne srabatyva- et (vozvrashchen nulevoj ukazatel'), to pechataetsya soobshchenie ob oshibke i programma zavershaetsya. Zatem v stroke 49 sozdaetsya imya vremennogo fajla s dobavleniem k nemu identifikatora processa, chtoby garantiro- vat' unikal'nost' imeni fajla. |tot fajl otkryvaetsya na chtenie i za- pis'. Esli eta operaciya ne udaetsya, pechataetsya soobshchenie ob oshibke i vypolnenie zavershaetsya. V strokah 57-103 zaklyuchen glavnyj cikl. Upravlyayushchaya chast' glav- nogo cikla opredelyaetsya tem, vse li dannye prochitany iz protokol'nogo fajla. Esli bol'she nikakie bajty prochitat' nel'zya, to fgets (stroka 57) vozvrashchaet nulevoj ukazatel', chto zavershaet cikl while. Kogda stroka dannyh chitaetsya iz protokol'nogo fajla, eti dannye pomeshchayutsya v massiv line. My primenyaem ukazatel' na simvol dlya prohoda vdol' stroki i poiska zapisi o narushitele. Izuchaya zapis' v vashem fajle sulog, vy mozhete uvidet', gde naho- dyatsya interesuyushchie nas polya. Snachala ukazatel' smeshchaetsya na 15 simvo- lov ot nachala stroki. |to poziciya flaga, opredelyayushchego, byla li us- peshnoj komanda su. Esli ona byla uspeshnoj, ukazatel' uvelichivaetsya na dva, chtoby propustit' probel i ustanovit' ukazatel' na imeni termina- la. |to imya imeet peremennuyu dlinu, poetomu my orientiruemsya po pro- belu v konce imeni. V strokah 63-64 primenyaetsya cikl while, kotoryj zastavlyaet ukazatel' propustit' vse simvoly, otlichnye ot probela. Za- tem on uvelichivaetsya na edinicu eshche raz, chtoby propustit' probel mezh- du imenem terminala i strokoj imeni pol'zovatelya. V etot moment ukazatel' nahoditsya v poslednem pole stroki. Uka- zatel' na eto pole pomeshchaetsya v peremennuyu uname, chtoby zatem ee mozh- no bylo ispol'zovat' dlya sravneniya strok. Sleduyushchij cikl while (stro- ki 66-67) prohodit po stroke, poka ne popadet na simvol defisa. Cikl while vypolnyaetsya do teh por, poka ukazatel' ne ukazyvaet na konec stroki (t.e. na nelevoj ukazatel', *p == '\0') i eshche ne ukazyvaet na defis. Poskol'ku v cikle ispol'zuetsya p++, to kogda my popadaem na nulevoj ukazatel', cikl zavershaetsya, prichem p ukazyvaet na sleduyushchij simvol. Vypolnyaetsya proverka, byl li superpol'zovatelem tot, kto prime- nil komandu su. Esli byl, to vzvoditsya flag alert, i my dolzhny prove- rit', razreshennyj li eto superpol'zovatel'. Cikl for (stroki 72-77) probegaet po vsem imenam v massive, soderzhashchem imena razreshennyh pol'zovatelej, do teh por, poka my ne obnaruzhim poslednyuyu zapis', ko- toraya yavlyaetsya pustoj. Stroka s imenem pol'zovatelya, ustanovlennaya predvaritel'no, sveryaetsya s kazhdoj zapis'yu v massive razreshennyh imen. Esli oni sovpadayut, to my mozhem predpolozhit', chto s dannym pri- meneniem komandy su vse v poryadke. Togda my vyklyuchaem flag alert i zavershaem sravnenie imen. Esli zhe po okonchanii cikla flag alert vse eshche vzveden, znachit imya ne soderzhitsya v spiske razreshennyh - eto, vozmozhno, narushitel'. Vsya zapis' celikom zapisyvaetsya vo vremennyj fajl i upravlenie peredaetsya nazad v nachalo cikla dlya sleduyushchej ope- racii chteniya. Kogda vse dannye prochitany, cikl while zavershaetsya. V stroke 84 proveryaetsya, vzveden li flag mail. Esli da, to vremennyj fajl zakry- vaetsya (chtoby srabotala komanda cat) i vypolnyaetsya eshche odin cikl for (stroki 87-91). On perebiraet vseh administratorov i zavershaetsya, kogda popadaet na nulevoj ukazatel' v konce massiva. Dlya kazhdogo iz oboznachennyh administratorov konstruiruetsya komanda mail i posylaetsya v sistemu UNIX pri pomoshchi sistemnogo vyzova (stroka 90). Metod otp- ravki po pochte vremennogo fajla zaklyuchaetsya v primenenii k etomu faj- lu komandy cat i peredache dannyh po konvejeru komande mail. Esli flag mail vyklyuchen, to vremennyj fajl nuzhno napechatat' v standartnyj vyvod, a ne otpravit' po pochte. Dlya togo chtoby sdelat' eto kak mozhno bystree, vremennyj fajl (kotoryj poka eshche otkryt) "pe- rematyvaetsya" (my pozicioniruemsya v ego nachalo) i posimvol'no propus- kaetsya po ciklu. Obratite vnimanie, chto dannyj cikl yavlyaetsya serdce- vinoj komandy cat, kak opisano na stranice 153 knigi Kernigana i Ritchi "YAzyk programmirovaniya Si" (B.W.Kernighan, D.M.Ritchie. The C Programming Language). Posle togo kak vremennyj fajl napechatan, on zakryvaetsya. Nakonec, zakryvaetsya protokol'nyj fajl i udalyaetsya vre- mennyj fajl.  * GLAVA 10. Smeshannye priemy *  Vvedenie Sposoby preobrazovaniya v yazyke shell conv Moduli preobrazovaniya dtoh dtoo htod htoo Tonkosti bc otod otoh Priemy yazyka shell dlya obespecheniya gibkosti programm Hitrosti yazyka shell CHitajte vvod s klaviatury, poka nahodites' v cikle, prisoedinennom k programnomu kanalu Zapusk dochernego yazyka shell Urovni yazyka shell i vvod-vyvod Vstroennyj vvod S redaktorom ed S fajlom a.out C arhivami yazyka shell Upravlenie statusom cikla Fil'try i sintaksis Nedostatki/osobennosti programmirovaniya na yazyke shell Programma dlya perenapravleniya oshibki Nekorrektnyj kod vozvrata Hitrosti redaktora Vi Vozvrashchenie v yazyk shell Podderzhka Escape Makrosy Komanda "One-Liners" - kroshechnaya, no moshchnaya . - 2 - Vvedenie |ta kniga yavlyaetsya itogom mnogoletnej raboty po podboru i razvitiyu instrumental'nyh sredstv OS UNIX. Mnogie veshchi, kotorye ne hotelos' by ostavlyat' bez vnimaniya, ne vpisalis' v kontekst predydushchih glav. |to i zakonchennye procedury, podobnye predstavlennym ranee, i nebol'shie, no ochen' moshchnye fragmenty programm. Krome togo, vyskazany nekotorye poleznye idei i predstavleny metody obrabotki obshchih situacij na yazyke shell. Sposoby preobrazovaniya Poskol'ku komp'yutery i ih rezidentnye utility ispol'zuyut pri rabote raznye sistemy schisleniya, chasto voznikaet neobhodimost' preobrazovaniya osnovanij sistem schisleniya. |ti preobrazovaniya obespechivayutsya horosho znakomymi specialistam komandami UNIX bc (kal'kulyator proizvol'noj tochnosti) i dc (kotoraya predpolozhitel'no rasshifrovyvaetsya kak nastol'nyj kal'kulyator ("desk calculator")). Bol'shinstvo iz sushchestvuyushchih vozmozhnostej libo nosyat ochen' ogranichennyj harakter, libo ih tyazhelo ispol'zovat' v ryade situacij, poetomu budet rassmotren vopros kak ispol'zovat' sushchestvuyushchie vozmozhnosti UNIX, chtoby lyuboe preobrazovanie bylo kak mozhno bolee legko osushchestvimym. --------------------------------------------------------------------- Nazvanie: conv --------------------------------------------------------------------- conv Perevodit chisla iz odnoj sistemy schisleniya v druguyu Naznachenie: Obespechivaet vozmozhnost' preobrazovaniya osnovaniya sistemy schisleniya Vyzov conv Primer vyzova: $conv Vyzvat' glavnoe menyu razlichnyh preobrazovanij 2 Vybrat' opciyu 2 ( iz shestnadcatirichnoj v desyatichnuyu) FFF Vvesti shestnadcatirichnoe chislo FFF. Na vyhode programmy poluchim desyatichnyj ekvivalent Ishodnyj tekst dlya funkcii conv 1 : 2 # @(#) conv v1.0 Preobrazovanie osnovaniya sistemy schisleniya, ispol'zuya shell Avtor: Russ Sage 3 4 while : 5 do 6 echo " 7 8 Preobrazovanie osnovanij 9 ------------------------ 10 1 - Desyatichnoe v shestnadcatirichnoe 11 2 - SHestnadcatirichnoe v desyatichnoe 12 3 - Desyatichnoe v vos'merichnoe 13 4 - Vos'merichnoe v desyatichnoe 14 5 - Vos'merichnoe v shestnadcatirichnoe 15 6 - SHestnadcatirichnoe v vos'merichnoe 16 17 enter choice (1-6, <>): \c" 18 read CHOICE 19 20 case $CHOICE in 21 "") exit;; 22 1) echo "\pVvedite desyatichnoe chislo (<> to exit): \c" 23 read DEC 24 if [ "$DEC" = ""] 25 then exit 26 fi 27 HEX='. dtoh' 28 echo "\n${DEC}d = ${HEX}x";; 29 2) echo"\nVvedite shestnadcatirichnoe chislo v verhnem registre (<> to exit): \c" 30 read HEX 31 if [ "$HEX" = ""] 32 then exit 33 fi 34 DEC='. htod' 35 echo "\n${HEX}x= ${DEC}d;; 36 3) echo "\nVvedite desyatichnoe chislo v verhnem registre (<> to exit): \c" 37 read DEC 38 if [ "$DEC" = ""] 39 then exit 40 fi 41 OCT='. dtoo' 42 echo "\n${DEC}d = ${OCT}o";; 43 4) echo "\nVvedite vos'merichnoe chislo (<> to exit): \c" 44 read OCT 45 if [ "$OCT" = ""] 46 then exit 47 fi 48 OCT='. otod' 49 echo "\n${OCT}o = ${DEC}d";; 50 5) echo "\nVvedite vos'merichnoe chislo (<> to exit): \c" 51 read OCT 52 if [ "$OCT" = ""] 53 then exit 54 fi 55 HEX='. otoh' 56 echo "\n${OCT}o = ${HEX}x";; 57 6) echo "\nVvedite shestnadcatirichnoe chislo v verhnem registre (<> to exit): \c" 58 read NEH 59 if [ "$NEH" = ""] 60 then exit 61 fi 62 OCT='. htoo' 63 echo "\n${HEX}x = ${OCT}o";; 64 *) echo "\n$CHOICE-neizvestnaya komanda";; 65 esac 66 done Peremennye okruzheniya CHOICE - Vybor komand iz glavnogo menyu DEC - Vydaet desyatichnoe znachenie kak rezul'tat preobrazovaniya HEX - Vydaet shestnadcatirichnoe znachenie kak - 4 - rezul'tat preobrazovaniya OCT - Vydaet vos'merichnoe znachenie kak rezul'tat preobrazovaniya Opisanie Zachem nam nuzhna funkciya conv ? Vypolnenie chislovyh operacij bol'shogo ob®ema v komandnyh fajlah yazyka shell - eto daleko ne samaya horoshaya ideya. Komandnye fajly yavlya- yutsya ves'ma medlennymi sami po sebe, a vypolnenie matematicheskih ope- racij eshche bol'she zamedlyaet ih rabotu. Odnako, procedury yazyka shell imeyut matematicheskie vozmozhnosti, i Vy, vozmozhno, zahotite imi vospol'zovat'sya. Esli Vam nuzhno preobrazovat' neskol'ko chisel v pro- cesse napisaniya programmy, to dlya etoj celi dostatochno udobno vyzvat' proceduru yazyka shell. Poskol'ku conv - eto programma, upravlyaemaya menyu, Vam ne pridetsya bespokoit'sya o zapominanii slozhnogo sintaksisa, kotryj ispol'zuyut nekotorye sistemnye utility preobrazovaniya. CHto delaet conv? |to instrumental'noe sredstvo obespechivaet vozmozhnost' perevoda chisel iz odnoj sistemy schisleniya v druguyu. Mozhno perevodit' desyatichnye, shestnadcatirichnye i vos'merichnye dannye. CHislo, zapisannoe v odnoj iz etih form, mozhet byt' perevedeno v lyubuyu iz dvuh ostavshihsya form. Rezhim raboty programmy vybiraetsya iz glavnogo menyu. V menyu est' shest' punktov. Posle togo kak Vy vybiraete chislo mezhdu 1 i 6, programma prosit Vas vvesti chislo kotoroe Vy hotite preobrazovat'. Proishodit preobrazovanie i na vyhode programmy Vy poluchaete dva znacheniya - chislo, kotoroe Vy preobrazovyvaete i chislo, k kotoromu ono bylo preobrazovano. Preobrazovaniya osushchestvlyayutsya putem vyzova vneshnih procedur, o kotoryh budet idti rech' dal'she v etoj glave, tak chto pered zapuskom conv neobhodimo ubedit'sya, chto Vy vklyuchili ih v vashu sistemu i razmestili v tom zhe kataloge, chto i conv. Esli Vy vvedete komandu, ne voshedshuyu v vysheupomyanutyj perechen', to budet vydano soobshchenie ob oshibke i opyat' budet vyvedeno glavnoe menyu. Poyasnenie Stroki 4-66 - eto odin bol'shoj beskonechnyj cikl while. My ispol'zuem beskonechnyj cikl, chtoby v sluchae oshibochnogo vvoda programma vernulas' v glavnoe menyu dlya povtornogo vvoda. Dlya togo, chtoby vyjti iz programmy, nuzhno prervat' cikl, t.e. vyjti iz cikla. Stroki 6-17 pechatayut menyu i vydayut podskazku dlya vybora. Esli Vy prosto nazhmete "Vvod", programma zavershit svoyu rabotu. Stroka 18 chitaet vvod s klaviatury, i stroki 20-65 vypolnyayut vybor po usloviyu dlya etoj velichiny. Esli poluchen nulevoj (pustoj) vvod, to programma zavershaet svoyu rabotu. Stroki 22-28 osushchestvlyayut perevod chisel iz desyatichnoj v shestnadcatirichnuyu sistemy schisleniya. Poskol'ku vse moduli perevoda otvechayut odnomu i tomu zhe obrazcu, to detal'no my rassmotrim tol'ko dannyj modul'. Podskazka zaprashivaet chislo v stroke 23. V strokah 24-26 proveryaetsya, ne bylo li vvedennoe znachenie pustym. Stroka 27 vyglyadit neskol'ko zagadochno, vyzyvaya odin iz vneshnih komandnyh fajlov dtoh dlya preobrazovaniya desyatichnyh chisel v shestnadcatiirichnye. Obratite vnimanie na to kak odna programma vypolnyaet druguyu. Komandnyj fajl dtoh zapuskaetsya, ispol'zuya komandu ".". |to oznachaet : "Vypolnite programmu, ispol'zuya tot zhe shell". Procedura dtoh ispol'zuet peremennuyu DEC dlya vvoda chisla i vydaet - 5 - preobrazovannoe chislo na standartnyj vyvod. CHtoby zapisat' eto chislo v peremennuyu, my delaem prisvoenie, potom zapuskaem programmu, ispol'zuya komandnuyu podstanovku. Stroka 28 vydaet na ekran pervonachal'noe desyatichnoe chislo i shestnadcatirichnoe, k kotoromu ono bylo preobrazovano. Varianty 2, 3, 4, 5 i 6 rabotayut analogichno. Edinstvennoe, chto menyaetsya - eto imya peremennoj, kotoroe sootvetstvuet tipu preobrazovaniya i nazvanie komandnogo fajla (skripta), kotoryj vyzyvaetsya dlya etogo preobrazovaniya. Moduli preobrazovaniya Teper' davajte rassmotrim otdel'no kazhdyj iz modulej perevoda. |ti moduli ili komandnye fajly yazyka shell ispol'zuyut komandu UNIX bc, chtoby osushchestvlyat' preobrazovaniya osnovanij sistem schisleniya. Nel'zya skazat', chto komanda bc - eto naibolee prostoj i udobnyj sposob perevoda, no tem ne menee ona rabotaet, i edinstvennoe, chto nam nuzhno, - eto izuchit' ee i pomestit' v komandnyj fajl. --------------------------------------------------------------------- Nazvanie : dtoh --------------------------------------------------------------------- dtoh Desyatichnye v shestnadcatirichnye. Naznachenie: Preobrazovyvaet vhodnye desyatichnye chisla v vyhodnye shestnadcatirichnye chisla. Sintaksis: $DEC="decimal_number"; HEX='.dtoh' Primer vyzova $DEC="25";HEX='.dtoh' $echo $HEX Prisvoit' DEC nachal'noe znachenie 25, vyzvat' dtoh dlya ego preobrazovaniya i zapisat' rezul'tat v HEX. Vyvesti rezul'taty na ekran. Ishodnyj tekst dlya dtoh 1 : 2 # @(#) dtoh v1.0 Preobrazovanie yazyka shell--desyatichnye v shestnadcatirichnye Avtor: Russ Sage 3 4 bc < HEX $ echo "shestnadcatirichnoe chislo: 'cat HEX'" Oboznachenie () zapuskaet vyzyvaemuyu proceduru v dochernem yazyke shell. Ispol'zuya "." dlya ee vypolneniya, my po prezhnemu imeem dostup k peremennoj DEC. Standartnyj vyvod perenapravlyaetsya v HEX. |ho soprovozhdenie poluchaet znachenie, ispol'zuya komandnuyu podstanovku. Rezul'tat cat pomeshchaetsya v eho predlozhenie. --------------------------------------------------------------------- Nazvanie: dtoo --------------------------------------------------------------------- dtoo Desyatichnye v vos'merichnye Naznachenie Perevodit vhodnye desyatichnye chisla v vyhodnye vos'merichnye. Sintaksis: DEC="decimal_number"; OCT='.dtoo' Primer vyzova $DEC="16";OCT='.dtoo' - 7 - $echo $OCT Prisvoit' DEC nachal'noe znachenie 16, vyzvat' dtoo dlya ee preobrazovaniya i zapisat' rezul'tat v OCT. Vyvesti rezul'taty na ekran. Ishodnyj tekst dlya dtoo 1 : 2 # @(#) dtoo v1.0 Preobrazovanie yazyka shell--desyatichnye v vos'merichnye Avtor: Russ Sage bc <