Упатство:Програмирање во Bash
За да продолжите со читање на ова упатсво, строго препорачуваме да ги имате основните знаења за Bash школката и основните команди за таа школка. Основно познавање на GNU/Linux основните команди. Пожелно е и некое искуство со програмски јазици. Иако ова упатство не е увод во програмирање, сепак опфаќа некои основни концепти.
Креирање едноставни скрипти
Традиционалната hello world скрипта
#!/bin/bash echo Hello World
Оваа скрипта е составена од 2 линии код. Првата линија ни објаснува која програма системот да ја користи за да ја стартува датотеката.
Втората линија е единствената акција изведена од скриптата, која го принта текстот 'Hello world' на вашиот терминал. Ако добиете нешто слично како ./hello.sh:Command not found, тогаш најверојатно имате грешка во првата линија
'#!/bin/bash'. Побарајте со 'whereis bash' или погледнете во делот 'Барајќи го bash' за да видите како точно да ја напишете оваа линија код.
Едноставна скрипта за бекап
#!/bin/bash tar -cZf /var/my-backup.tgz /home/me/
Во оваа скрипта наместо испринтана порака на терминалот, ние креираме tar-ball од ’home’ корисничкиот директориум. Оваа скрипта не е баш наменета за употреба, подобра и покорисна бекап скрипта ќе биде презентирана подоцна во овој документ.
Пренасочување
Теорија и краток преглед
Постојат 3 опишувачи на датотеки, stdin, stdout и stderr (std=стандард).
Во основа можете:
- да го пренасочите stdout во некоја датотека
- да го пренасочите stderr во некоја датотека
- да го пренасочите stdout во stderr
- да го пренасочите stderr во stdout
- да ги пренасочите stderr и stdout во некоја датотека
- да ги пренасочите stderr и stdout во stdout
- да ги пренасочите stderr и stdout во stderr
1 претстатува stdout (стандарден излез) и 2 stderr (стандарден излез за грешки).
Мала забелешка околу овие работи: со наредбата less можете да ги видите и двата stdout(кој останува во баферот) и stderr кој ќе биде испечатен на екранот, но избришан доколку се обидете да го прелистувате или прегледувате баферот.
Пример: stdout во датотека
Овој пример ќе предизвика излезот од програмот на екранот да биде запишан во некоја датотека.
ls -l > ls.l.txt
Овде, датотеката со име 'ls.l.txt' ќе биде креирана и ќе биде составена од она што го гледате на екранот која ја куцате и извршувате наредбата 'ls -l'.
stderr во датотека
Овој пример ќе предизвика stderr излезот од програмот да биде запишан во датотека.
grep da * 2> grep-errors.txt
Овде, датотеката со име 'grep-errors.txt' ќе биде креирана и ќе биде составена од stderr делот од излезот при извршувањето на 'grep da *' наредбата.
stdout кон stderr
Овој пример ќе предизвика stderr излезот од програмот да биде запишан во истиот покажувач на датотеки него stdout.
grep da * 1>&2
Овде, stdout делот од наредбата е испратен до stderr, можете да го забележите тоа на најразлични начини.
Пример: stderr кон stdout
Овој пример ќе предизвика stderr излезот од програмот да биде запишан во истиот покажувач на датотеки него stdout.
grep * 2>&1
Овде, stderr делот од наредбата е испратен до stdout, ако ставите pipe до less, ќе видите дека линиите кои нормално 'исчезнуваат'(кои што се запишани во stderr) се зачувани сега (затоа што тие се во stdout).
stderr и stdout до датотека
Овој пример ќе го смести секој излез од програмот во некоја датотека. Ова е згодно понекогаш, бидејќи може да се комбинира со cron, ако сакаме наредбата да помине во апсолутна тишина.
rm -f $(find / -name core) &> /dev/null
Ова (размислувајќи за запишувањето во cron) ќе ја избрише секоја датотека со име 'core' во било кој директориум. Најважно е да бидете сигурни што прави оваа наредба, доколку сакате да го избришете нејзиниот излез.
Протоци (pipes)
Ова поглавје ја објаснува на практичен начин како да користите протоци и зошто би сакале да ги употребувате баш нив.
Која е улогата на протоци, и зошто би ги користел
протоците дозволуваат да се користи излезот на некоја програма како влез на некоја друга.
Протоци и sed
Ова е најобичен начин на користење на протоците.
# ls -l | sed -e "s/[aeio]/u/g"
Еве што се случува овде: Прво наредбата ls -l се извршува, и нејзиниот излез наместо да биде испринтан на екран, е испратен (преку проток) до sad програмот, кој што принта тоа што мора.
Алтернатива до ls -l*.txt
Најверојатно, ова е потешкиот начин да се направи ls -l*.txt, но овде ќе го користите за да ги илустрираме протоците, а не да решаваме некоја дилема
# ls -l | grep "\.txt$"
Овде, излезот од програмата ls -l е испратен преку grep програмата, кој по редослед ќе ги испринта линиите кои одговараат со "\.txt$".
Променливи ($)
Променливите се користат во сите програмски јазици. Нема типови на податоци. Променливата во беш (bash) може да биде број, карактер или низа од карактери. Нема потреба од декларација на променливата, таа ќе се креира само со доделувањето на вредност на нејзината референца.
Hello World! со променливи
#!/bin/bash STR="Hello World!" echo $STR
Втората линија, креира променлива со име STR и е иницијализирана со стрингот 'Hello World' кадешто вредноста на оваа променлива се надополнува со знакот '$'на почетокот.Важно е дека ако не се стави '$' знакот пред променливата, тогаш излезот од програмата ќе биде друг, сигурно не на оној начин на којшто посакуваме да работи.
Проста скрипта за бекап 2
#!/bin/bash OF=/var/my-backup-$(date +%Y%m%d).tgz tar -cZf $OF /home/me/
Скриптата не запознава со друго нешто. Најпрво од се, треба да бидеме запознаени со декларацијата и иницијализацијата на променливите во вториот ред од кодот. Забележи го изразот '$(date +%Y%m%d)'. Ако ја извршите оваа скрипта ќе забележите дека ги извршува командите внатре во заградите, прикажувајќи го излезот од нив. Забележете дека во оваа скрипта, името на излезната датотека ќе биде различно секој ден врз основа на промената на форматот од date наредбата (+%Y%m%d). Ова можете да го промените со додавање на друг формат.
Локални променливи
Локалните променливи можат да бидат креирани со користење на клучниот збор 'local'
#!/bin/bash HELLO=Hello function hello { local HELLO=World echo $HELLO } echo $HELLO hello echo $HELLO
Овој пример би требало да биде доволен, за да покаже како се користат локалните променливи.
Услови
Условите ни даваат за предност да одлучиме дали да се изврши некоја акција, или не, оваа одлука е земена со евалуирање на изразот.
Малку теорија
Условите имаат многу форми. Најпростата форма е:
if израз then наредба,
каде што наредбата ќе биде извршена само ако условот евалуира во точно пошто е од тип bool.'2<1' е израз кој евалуира во неточно, додека '2>1' евалуира во точно.Условите имаат и други форми како на пример: if израз then наредба1 else наредба2 . Кадешто наредба1 ќе биде извршена само ако изразот евалуира во точно, инаку наредба2 ќе биде извршена. Друга форма на формирање на услови е:
if израз1 then наредба1 else if израз2 then наредба2 else наредба3
Во оваа форма е додаден само „ELSE IF 'израз2' THEN 'наредба2', која прави наредба2 да биде извршена само ако израз2 евалуира во точно.
Околу синтаксата:
Основната форма за 'if' конструкцијата во bash е следнава:
if [израз]; then код ако if 'изразот' е точен. fi
Основен пример за услов
if-then
#!/bin/bash if [ "foo" = "foo" ]; then echo expression evaluated as true fi
Кодот ќе биде извршен ако изразот во големите загради е точен и се најде после клучниот збор 'then' и пред 'fi' којшто означува крај на кодот што се извршил по обработката на условот.
Основен пример за услов 2
if-then-else
#!/bin/bash if [ "foo" = "foo" ]; then echo expression evaluated as true else echo expression evaluated as false fi
Услови со променливи
#!/bin/bash T1="foo" T2="bar" if [ "$T1" = "$T2" ]; then echo expression evaluated as true else echo expression evaluated as false fi
Циклуси
- for циклусот е малку различен од другите програмски јазици. Дозволува итерации преку серии од зборови без употреба на низи.
- while извршува парче код ако контролниот израз е точен, и запира кога изразот ќе евалуира во неточно (or a explicit break is found within the executed code.)
- until е речиси ист со while (додека) циклусот, освен тоа што кодот се извршува додека контролниот израз евалуира во неточно.
Пример
#!/bin/bash for i in $( ls ); do echo item: $i done
Во вториот ред ние декларираме променливата да прими вредности од $(ls).Во третиот ред може да биде и подолг по потреба, или да има повеќе линии пред done. 'done' индицира дека кодот што ја користи вредноста на $i е завршен, и $i може да прими нова вредност.
for циклус во C/Perl стил
#!/bin/bash for i in `seq 1 10`; do echo $i done
Пример за while циклус
#!/bin/bash COUNTER=0 while [ $COUNTER -lt 10 ]; do echo The counter is $COUNTER let COUNTER=COUNTER+1 done
Оваа скрипта ’се такмичи’ со добро познатата (C, Pascal, perl, итн) 'for' структура.
= Пример за until циклус
#!/bin/bash COUNTER=20 until [ $COUNTER -lt 10 ]; do echo COUNTER $COUNTER let COUNTER-=1 done