File: Bash-Prog-Intro-HOWTO-NL.sgml

package info (click to toggle)
doc-linux-nl 20051127-2
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 16,408 kB
  • ctags: 94
  • sloc: xml: 47,403; makefile: 312; perl: 193; sh: 116; ansic: 12; csh: 9
file content (1250 lines) | stat: -rw-r--r-- 40,864 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
<!doctype linuxdoc system>
<linuxdoc>
<!-- 
     Een introductie bashshell programmeren
 -->

<!-- Titel informatie -->
<article>
<titlepag>
    <title>BASH Programmering - Introductie HOW-TO</title>
    <author><name>door Mike G <tt>mikkey at dynamo.com.ar</tt><newline>
    Vertaald door: Ellen Bokhorst, bokkie at nl.linux.org</name></author>
    <date>Do jul 27 09:36:18 ART 2000</date>
    <abstract> 
    Dit artikel is bedoeld om je te helpen een begin te maken met
    het programmeren van basis tot middelmatige shell-scripts. 
    Het is niet bedoeld als een document voor gevorderden (zie de titel).
    Ik ben GEEN expert noch een goeroe shellprogrammeur.
    Ik besloot dit te schrijven omdat ik er veel van zal leren en het wellicht
    van nut kan zijn voor andere mensen. Feedback wordt zeer gewaardeerd vooral
    in de vorm van een patch :).
    </abstract>
</titlepag>
<!-- Inhoudsopgave -->
<toc>

<!-- Requisites -->
<sect>
<heading>Introductie</heading>
<sect1>
<heading>Ophalen van de laatste versie</heading>

<p>
<htmlurl url="http://www.linuxdoc.org/HOWTO/Bash-Prog-Intro-HOWTO.html" 
     name="http://www.linuxdoc.org/HOWTO/Bash-Prog-Intro-HOWTO.html">
</p>

     </sect1>

     <sect1>
<heading>Benodigdheden</heading>
          <p> Bekendheid met GNU/Linux opdrachtregels, en bekendheid met
          basisprogrammeerconcepten is prettig. Alhoewel dit geen introductie
          is in programmeren, wordt er van veel basisconcepten een uitleg
          gegeven (of op z'n minst wordt dit geprobeerd).
          </p> 
     </sect1>
     <sect1>
     <heading>Gebruik van dit document</heading>
          <p>Dit document probeert te helpen bij de volgende situtaties
	  <itemize>
	      <item>Je hebt een idee over programmeren en je wilt beginnen
              een aantal shellscripts te coderen.</item>
	      <item>Je hebt een vaag idee over shellprogrammering en wilt
              een soort van referentie.</item>
	      <item>Je wilt een aantal shellscripts zien met wat opmerkingen
              om te beginnen je eigen shellscripts te gaan schrijven.</item>
	      <item>Je gaat over van DOS/Windows (of je deed dit al) en wil
              "batch" processen maken.</item>
	      <item>Je bent een echte nerd en leest iedere beschikbare how-to
              </item>
	  </itemize></p>
     </sect1>
</sect>

<!-- Zeer eenvoudige Scripts --> 
<sect><heading>
Zeer eenvoudige Scripts</heading>

    <p>In deze HOW-TO wordt getracht je een aantal hints te geven over
    shellscriptprogrammering welke sterk is gebaseerd op voorbeelden.</p>
    <p>In deze sectie zijn een aantal kleine scripts te vinden die je
    hopelijk op weg helpen een aantal technieken te doorgronden.</p>

    <sect1><heading>
    Traditioneel hello world script</heading>

        <p><!-- __TO-DO__
	someone suggested using this instead of the line numbering 
	but it doesn't work on verion 1.0.9
	<pre></pre> 
	--></p>
	<p>
	<tscreen><verb>
	  #!/bin/bash          
	  echo Hello World    
	</verb></tscreen></p>
	 
	<p>Dit script bestaat slechts uit twee regels.
        In de eerste regel wordt het systeem duidelijk gemaakt welk programma
        moet worden gebruikt om het bestand uit te voeren.</p>
        <p>De tweede regel bestaat uit alleen die actie waarmee 'Hello World!
        op de terminal wordt afgedrukt.</p>
        <p>Als je iets krijgt als <it>./hello.sh: Command not found.</it>
        is waarschijnlijk de eerste regel `#!/bin/bash' niet goed, roep
        `whereis bash' of zie `bash zoeken' om te bezien hoe je deze regel
        zou moeten schrijven.</p>
    </sect1>
    <sect1>
    <heading>Een zeer eenvoudig backupscript</heading>
        <p>
	<tscreen><verb>
	#!/bin/bash          
	tar -cZf /var/my-backup.tgz /home/me/
	</verb></tscreen></p>
        <p>In plaats dat er nu een bericht op de terminal wordt weergegeven,
        maken we in dit script een tar-ball van de homedirectory van een
        gebruiker. Het is niet de bedoeling dat dit wordt gebruikt. Later in
        dit document wordt een handiger backupscript gepresenteerd.</p>
    </sect1>   
</sect>


<!-- Omleiding -->
<sect><heading>Alles over omleiding</heading>

	<sect1><heading>Theorie en snelle naslag</heading>
	<p>Er zijn 3 file descriptors, stdin, stdout en stderr (std=standaard).
</p>

	<p>In principe kun je:
	<enum>
	<item> stdout naar een bestand omleiden</item>
	<item> stderr naar een bestand omleiden</item>
	<item> stdout naar stderr omleiden</item>
	<item> stderr naar stdout omleiden</item>
	<item> stderr en stdout naar een bestand omleiden</item>
	<item> stderr en stdout naar stdout omleiden</item>
	<item> stderr en stdout naar stderr omleiden</item>
	</enum>
	1  is een representatie van stdout en 2 van stderr.</p>
	<p> Een opmerking hierover: met de opdracht less kun je zowel
        stdout (welke in de buffer blijft) en stderr, welke op het scherm
        wordt weergegeven, bekijken, maar is verwijderd als je door de buffer
        probeert te 'bladeren'.
	</p>
	</sect1>
	
	<sect1><heading>Voorbeeld: stdout naar bestand</heading>
	<p>Hiermee wordt de uitvoer van een programma naar een bestand
        weggeschreven.
	<tscreen><verb>
	ls -l > ls-l.txt
	</verb></tscreen>
	Hier zal een bestand, genaamd 'ls-l.txt' worden aangemaakt en hierin
        zal worden opgevangen wat je krijgt als je de opdracht 'ls -l' typt
        en uitvoert.</p>
	</sect1>

	<sect1><heading>Voorbeeld: stderr naar bestand</heading> 
	<p> Dit zorgt dat de uitvoer van stderr van een programma naar
        een bestand wordt weggeschreven.
	<tscreen><verb>
	grep da * 2> grep-errors.txt
	</verb></tscreen>
	Hier zal een bestand, genaamd 'grep-errors.txt' worden aangemaakt en
        hier zal dan het stderr gedeelte van de uitvoer in staan van de
        opdracht 'grep da *'.</p>
	</sect1>

	<sect1><heading>Voorbeeld: stdout naar stderr</heading>
	<p>Dit zorgt dat de sterr uitvoer van een programma naar
        dezelfde filedescriptor als stdout wordt weggeschreven.
	<tscreen><verb>
	grep da * 1>&2 
	</verb></tscreen>
	Hier wordt het stdout gedeelte van de opdracht naar stderr gezonden,
        je merkt dat mogelijk op verschillende manieren.</p>
	</sect1>

	<sect1><heading>Voorbeeld: stderr naar stdout</heading>
	<p> Dit zorgt dat de stderr uitvoer van een programma naar
        dezelfde filedescriptor wordt weggeschreven als stdout.
	<tscreen><verb>
	grep * 2>&1
	</verb></tscreen>
	Hier wordt het stderr gedeelte van de opdracht naar stdout gestuurd,
        als je middels een pipe-symbool de uitvoer naar less stuurt, zul je
        zien dat de regels die normaal gesproken 'verdwijnen' (als ze naar
        stderr worden geschreven) nu behouden blijven (omdat ze zich op
        stdout bevinden).</p>
	</sect1>

	<sect1><heading>Voorbeeld: stderr en stdout naar bestand</heading> 
	<p> Hiermee zal alle uitvoer van een programma in een bestand worden
        geplaatst. Soms is dit geschikt voor cron entries, als je een opdracht
        in absolute stilte wilt laten uitvoeren.
	<tscreen><verb>
	rm -f $(find / -name core) &> /dev/null 
	</verb></tscreen>
	Dit (denkend aan een cron entry) zal ieder bestand genaam 'core'
        in iedere directory verwijderen. Merk op dat je er nogal zeker
        van moet zijn wat een opdracht doet als je de uitvoer ervan gaat
        verwijderen.</p>
	</sect1>
<!--
redirect stderr en stdout naar stdout 
redirect stderr en stdout naar stderr
-->



<!--
	<sect1>
	Voorbeeld: 
	<p> Hiermee zal
	<tscreen><verb>
	opdracht
	</verb></tscreen>
	Uitleg
	</sect1>
-->

</sect>

<!-- pipes -->
<sect><heading>Pipes</heading>
<p>In deze sectie wordt op een zeer eenvoudige en praktische wijze uitgelegd
hoe gebruik te maken van het pipe-symbool en waarvoor je het zou kunnen
gebruiken.
</p>

<sect1><heading>
Wat het zijn en waarvoor je het zou kunnen gebruiken</heading>
<p> Pipe-symbolen laten je gebruik maken van (zeer eenvoudig uitgelegd) de
uitvoer van een programma als de invoer van een ander programma.</p>
</sect1>

<sect1><heading>Voorbeeld: eenvoudige pipe met sed</heading>
<p> Dit is een zeer eenvoudige manier om gebruik te maken van een
pipe-symbool.
<tscreen><verb>
ls -l | sed -e "s/[aeio]/u/g"	
</verb></tscreen>
Wat er hier gebeurt is het volgende: eerst wordt de opdracht 'ls -l' 
uitgevoerd, en in plaats dat de uitvoer ervan wordt afgedrukt, wordt
het naar het programma sed gestuurd (piped), wat op zijn beurt afdrukt wat
het moet afdrukken.</p>
</sect1>

<sect1><heading>Voorbeeld: een alternatief voor ls -l *.txt</heading>
<p> Waarschijnlijk is dit een moeilijkere manier om een ls -l *.txt uit
te voeren, maar het dient hier ter illustratie, niet voor het oplossen van
een opsommingsdilemma.
<tscreen><verb>
ls -l | grep "\.txt$"
</verb></tscreen>
Hier wordt de uitvoer van het programma ls -l naar het grep programma
gezonden, welke op zijn beurt de regels afdrukt die overeenkomen met de
reguliere expressie "\.txt$".</p>
</sect1>



<!--
	<sect1>
	Voorbeeld: 
	<p> Dit zal
	<tscreen><verb>
	opdracht
	</verb></tscreen>
	Uitleg
	</sect1>
-->


</sect>


<!-- Variabelen -->
<sect><heading>
Variabelen</heading>

    <!-- Droge Theorie -->
        <p> Je kunt net als in iedere andere programmeertaal gebruik maken
        van variabelen. Er zijn geen gegevenstypen.
	Onder bash kan een variabele bestaan uit een nummer, een teken, of een
        reeks tekens.</p>
	<p>Je hoeft een variabele niet te declareren. Door er slechts een
        waarde aan toe te kennen zal het worden aangemaakt.</p>


    <!-- Voorbeelden -->
        <sect1><heading>
	Voorbeeld: Hello World! door gebruik te maken van variabelen</heading>
            <p> 
	    <tscreen><verb>
	    #!/bin/bash          
	    STR="Hello World!"
	    echo $STR    
	    </verb></tscreen></p>

	    <p>In regel 2 wordt een variabele aangemaakt met de naam STR
            en hieraan wordt de string "Hello World!" toegekend.
	    De WAARDE van deze variabele wordt vervolgens opgehaald door er
            een '$' voor te plaatsen.
	    Let er alsjeblieft op (probeer het uit!) dat als je het '$' teken
            niet gebruikt, de uitvoer van het programma iets anders zal zijn,
            en het waarschijnlijk niet datgene zal zijn wat je wilt dat 't is.
            </p>
	</sect1>
        <sect1><heading>
	   Voorbeeld: Een zeer eenvoudig backupscript (iets beter)</heading>
	   <p> 
	   <tscreen><verb>
	   #!/bin/bash          
	   OF=/var/my-backup-$(date +%Y%m%d).tgz
	   tar -cZf $OF /home/me/
	   </verb></tscreen></p>
	   <p>In dit script wordt iets anders ge&iuml;ntroduceerd. Ten
           eerste zou je nu bekend moeten zijn met de aanmaak van de
           variabele en de toekenning in regel 2. Let op de expressie
	   `$(date +%Y%m%d)'.
	   Als je het script uit laat voeren, zal je bemerken dat het
           de opdracht binnen de haakjes uitvoert, en de uitvoer ervan
           afvangt.</p>

	   <p>Merk op dat de naam van het bestand, de uitvoer, iedere dag
           anders zal zijn, vanwege de opmaakoptie van de opdracht date 
	   (+%Y%m%d). Je kunt dit wijzigen door een ander formaat op te geven.
           </p>
	   <p>Nog wat meer voorbeelden:</p>
	   <p> echo ls</p>
	   <p> echo $(ls)</p>
	</sect1>   

<sect1><heading>Lokale variabelen</heading>

<p> Lokale variabelen kunnen worden aangemaakt door gebruik te maken van het
keyword <it>local</it>.

<tscreen><verb>
	#!/bin/bash
	HELLO=Hello 
	function hello {
		local HELLO=World
		echo $HELLO
	}
	echo $HELLO
	hello
	echo $HELLO
</verb></tscreen>
	Dit voorbeeld zou genoeg moeten zijn om aan te tonen hoe je
        een lokale variabele gebruikt.
	</p>
	</sect1>
 </sect>

<!-- Voorwaardelijke opdrachten -->
<sect>
<heading>Voorwaardelijke opdrachten</heading>
    
    <p>Voorwaardelijke opdrachten laten je een beslissing nemen of een
    actie wel of niet zal worden uitgevoerd, de beslissing wordt genomen door
    de waarde te bepalen van een expressie.</p>

    <!-- Droge Theorie -->
    <sect1><heading>
    Droge Theorie</heading>
        <p>Voorwaardelijke opdrachten bestaan er in veel vormen. 
        De basisvorm is:
	<bf>if</bf> <it/expressie</it> <bf>then</bf> <it/statement</it>
	hierbij wordt 'statement' alleen uitgevoerd wanneer de 'expressie'
        de waarde true oplevert.</p> 	
	<p>`2&lt;1' is een expressie die de waarde false oplevert, 
	terwijl `2&gt;1' 
	de waarde true oplevert.</p>
	<p> Er zijn nog andere vormen voorwaardelijke opdrachten, zoals:
	<bf/if/ <it/expressie/ 
	<bf/then/ <it/statement1/ <bf/else/ <it/statement2/.
	Hier wordt 'statement1' uitgevoerd als de 'expressie' true
        oplevert, anders wordt 'statement2' uitgevoerd.</p>
	<p>Nog een andere vorm van een voorwaardelijke opdracht is:
	<bf/if/ <it/expressie1/ 
	<bf/then/ <it/statement1/ 
	<bf/else if/ <it/expressie2/ <bf/then/ <it/statement2/ 
	<bf/else/ <it/statement3/
	In deze vorm is slechts de
	"ELSE IF 'expressie2' THEN 'statement2'" toegevoegd wat 
        maakt dat statement2 wordt uitgevoerd als expressie2 de waarde true
        oplevert. De rest is wat je er zelf van maakt. 
        (zie vorige vormen).</p>
	<p> Iets over syntax:</p>
	<p> De basis van een 'if' constructie onder bash is:</p>
	<p> if [expressie];</p>
	<p> then</p>
	<p>    code als 'expressie' is true.</p>
	<p> fi</p>
    </sect1>
    <!-- Voorbeelden -->
        <sect1><heading>
	Voorbeeld: Basis voorwaardelijke opdracht if .. then</heading>
            <p> 
	    <tscreen><verb>
	    #!/bin/bash
	    if [ "foo" = "foo" ]; then
	       echo waarde van expressie leverde true op
	    fi
	    </verb></tscreen>
	    </p> 
            <p>De code die zal worden uitgevoerd als de expressie tussen de
            blokhaken true oplevert, is te vinden achter het 'then' woord en
            voor het 'fi' woord waarmee het einde van de voorwaardelijk
            uit te voeren code wordt aangegeven.</p>
	</sect1>
	<sect1><heading>
	Voorbeeld: Voorbeeld basis voorwaardelijke opdracht if .. then ... else
	</heading>
            <p>
	    <tscreen><verb>
	    #!/bin/bash
	    if [ "foo" = "foo" ]; then
	       echo expressie levert de waarde true op
	    else
	       echo expressie levert de waarde false op
	    fi
	    </verb></tscreen></p>
	</sect1>
	<sect1><heading>
	Voorbeeld: Voorwaardelijke opdrachten met variabelen</heading>
	    <p> 
	    <tscreen><verb>
	    #!/bin/bash
	    T1="foo"
	    T2="bar"
	    if [ "$T1" = "$T2" ]; then
	        echo expressie levert de waarde true op
	    else
	        echo expressie levert de waarde false op
	    fi
	    </verb></tscreen></p>
	</sect1>
</sect>

<!--
	<sect1>
	Voorbeeld: testen of een bestand bestaat
	    <p> nog &eacute;&eacute;n met dank aan mike
	    <tscreen><verb>
	    #!/bin/bash
	    FILE=~/.basrc
	    if [ -f $FILE ]; then
	        echo bestand $FILE bestaat
	    else
	        echo bestand niet gevonden
	    fi
	    if [ 'test -f $FILE']
	    </verb></tscreen>
	</sect1>
-->



<!-- Loops : for, while en until -->
<sect>
<heading>Loops for, while en until</heading>
    <!-- Droge Theorie -->

    <p>In deze sectie tref je for, while en until loops aan.</p>
    <p> De <bf/for/ loop werkt iets anders dan in andere programmeertalen.
    Eigenlijk laat het je een serie 'woorden' binnen een string herhalen.</p>
      <p>De <bf/while/ voert een stuk code uit als de controlerende 
      expressie true oplevert, en stopt alleen wanneer het false is
      (of als er binnen de
      uitgevoerde code een expliciete break werd gevonden).</p>
      <p>De <bf/until/ loop is bijna gelijk aan de while loop behalve dat
      de code  wordt uitgevoerd terwijl de controlerende expressie de waarde
      false oplevert.</p>
      <p>Als je het vermoeden hebt dat while en until erg op elkaar lijken, heb je gelijk.
    <!-- Voorbeelden --></p> 
    <sect1>
    <heading>Voorbeeld met for</heading>
        <p> 
	<tscreen><verb>
        #!/bin/bash
        for i in $( ls ); do
            echo item: $i
        done
        </verb></tscreen>
        </p> 
        <p>In de tweede regel, declareren we i als variabele voor de
        verschillende waarden in $( ls ).</p>
        <p>De derde regel zou zonodig langer kunnen zijn, of er zouden meer
         regels voor kunnen komen voor de done (4).</p>
        <p> `done' (4) geeft aan dat de code die de waarde van $i gebruikte
        be&euml;indigd is en $i een nieuwe waarde aan kan nemen.</p>
        <p>Dit script heeft weinig nut, en een nuttiger wijze om gebruik te
        maken van de for loop zou zijn het in het voorgaande voorbeeld 
        te gebruiken waarbij slechts bepaalde bestanden overeenkomen.</p>
    
    </sect1>

	<sect1><heading>Met C vergelijkende for</heading>
	<p> fiesh raadde het toevoegen van deze vorm van een loop aan. 
        Het is een for loop
        meer vergelijkbaar met die van C/perl...
	<tscreen><verb>
	#!/bin/bash
	for i in `seq 1 10`;
	do
		echo $i
	done	
	</verb></tscreen>
	</p>
	</sect1>

    <!-- while -->
    <sect1>
    <heading>Voorbeeld met while</heading>
         <p> <tscreen><verb>
         #!/bin/bash 
         COUNTER=0
         while [  $COUNTER -lt 10 ]; do
             echo De teller is $COUNTER
             let COUNTER=COUNTER+1 
         done
         </verb></tscreen>
	 </p>
	 <p> Dit script 'emuleert' de welbekende
	 (C, Pascal, perl, enz) 'for' structuur</p>
    </sect1>
    <!-- until -->
    <sect1>
    <heading>Until voorbeeld</heading>
         <p> <tscreen><verb>
         #!/bin/bash 
         COUNTER=20
         until [  $COUNTER -lt 10 ]; do
             echo COUNTER $COUNTER
             let COUNTER-=1
         done
	 </verb></tscreen></p>
    </sect1>
</sect>

<!-- Functions -->
<sect>
<heading>Functies</heading>
     <p>Zoals in bijna iedere programmeertaal, kun je functies gebruiken om
     stukken code op een wat logischer wijze te groeperen of te oefenen in
     de goddelijke kunst van recursie.</p>
     <p>Het declareren van een functie is slecht een kwestie van het
     schrijven van function mijn_func { mijn_code }.</p>
     <p>Het aanroepen van een functie is net als het aanroepen van ieder ander
     programma, je tikt gewoon de naam ervan in.</p>
     
     <sect1>
     <heading>Voorbeeld van een functie</heading>
           <p> <tscreen><verb>
	   #!/bin/bash 
	   function quit {
	   	exit
	   }
	   function hello {
	   	echo Hello!
	   }
	   hello
	   quit
	   echo foo 
	   </verb></tscreen></p>
	   <p>In de regels 2-4 staat de 'quit' functie. 
           In de regels 5-7 staat de 'hello' functie.
	   Als je er niet geheel zeker van bent wat dit script doet, probeer
           het dan uit!</p>
	   <p>Merk op dat functies niet in een specifieke volgorde hoeven te
           staan.</p>
	   <p>Bij het uitvoeren van het script, zal je bemerken dat als eerste
           de functie 'hello' wordt aangeroepen en ten tweede de 'quit'
           functie en de functie komt nooit bij regel 10.</p>
     </sect1>


     <sect1><heading>Voorbeeld van een functie met parameters</heading>
           <p> <tscreen><verb>
		#!/bin/bash 
		function quit {
 		   exit
		}  
		function e {
		    echo $1 
		}  
		e Hello
		e World
		quit
		echo foo 

	   </verb></tscreen>
Dit script is bijna identiek aan het voorgaande script. Het belangrijkste
verschil is de functie 'e'. Deze functie drukt het eerste argument dat het
ontvangt af. Argumenten binnen functies worden op dezelfde wijze behandeld
als argumenten die aan het script worden gegeven.
</p>
</sect1>
</sect>

<!-- User interfaces -->
<sect>
<heading>Gebruikersinterfaces</heading>
     <!-- Eenvoudige menu's met select -->

     <sect1>
     <heading>Het gebruik van select om eenvoudige menu's te maken</heading>
	   <p>
	   <tscreen><verb>
	   #!/bin/bash
	   OPTIONS="Hello Quit"
	   select opt in $OPTIONS; do
	       if [ "$opt" = "Quit" ]; then
	   	echo klaar
	   	exit
	       elif [ "$opt" = "Hello" ]; then
	   	echo Hello World
	       else
	   	clear
	   	echo onjuiste keuze
	       fi
	   done
	  </verb></tscreen> </p>
           <p>Als je dit script uitvoert, zal je zien dat dit de droom is
           van een programmeur voor op tekst gebaseerde menu's.
           Je zal waarschijnlijk bemerken dat het erg lijkt op de 'for'
           instructie, in plaats van dat ieder 'woord' in $OPTIONS wordt
           doorlopen, geeft het de gebruiker een prompt.
	   </p>
     </sect1>
    <!-- Gebruik maken van de opdrachtregel -->
    <sect1><heading>
    Gebruik maken van de opdrachtregel</heading>
         <p>
	 <tscreen><verb>
	  #!/bin/bash        
          if [ -z "$1" ]; then 
              echo usage: $0 directory
              exit
          fi
          SRCD=$1
          TGTD="/var/backups/"
          OF=home-$(date +%Y%m%d).tgz
          tar -cZf $TGTD$OF $SRCD
	 </verb></tscreen>
	 </p>
	 <p>Het zou je duidelijk moeten zijn wat dit script doet. 
         De expressie in de eerste voorwaardelijke opdracht test of het
         programma een argument ($1) meekreeg en stopt als het dit niet deed,
         waarbij een kort bericht over het gebruik aan de gebruiker wordt
         getoond. De rest van het script zou vanaf hier duidelijk moeten zijn.
         </p>
    </sect1>

</sect>

<!-- Misc -->
<sect>
<heading>Diversen</heading>
    <!-- Inlezen van gebruikersinvoer  -->    
    <sect1>
<heading>Inlezen van gebruikersinvoer met read</heading>
<p>In veel situaties wil je de gebruiker wellicht vragen om wat invoer, en
er zijn verscheidene manieren om dit te bereiken:
Dit is &eacute;&eacute;n van die manieren:
	<tscreen><verb>
		#!/bin/bash
		echo Vul alsjeblieft je naam in
		read NAME
		echo "Hi $NAME!"
	</verb></tscreen>
Een variant daarop zal het volgende voorbeeld verduidelijken waarmee
je meerdere waarden met read kan verkrijgen.
	<tscreen><verb>
		#!/bin/bash
		echo Vul alsjeblieft je voornaam en achternaam in
		read FN LN 
		echo "Hi! $LN, $FN !"
	</verb></tscreen>
</p>
</sect1>

    <!-- Arithmetic evaluation  -->    
    <sect1><heading>
    Rekenkundige waarde bepalen</heading>
         <p>Probeer het volgende achter de opdrachtregel (of in een shell):</p>
	 <p>echo 1 + 1</p>
	 <p>Als je verwachtte '2' te zien te krijgen, zal je wel teleurgesteld
         zijn. Wat als je wilt dat BASH van een aantal getallen de waarde
         bepaalt?
	 Dit is de oplossing:</p>
	 <p> echo $((1+1))</p>
	 <p>Hiermee zal een 'logischer' uitvoer worden geproduceerd.
         Dit is voor het bepalen van de waarde van een rekenkundige expressie.
	 Je kunt dit ook als volgt bereiken:</p>
	 <p> echo $[1+1]</p>
	 
	 <p>Als je breuken of meer rekenkunde nodig hebt of dit gewoon wilt,
         kun je bc gebruiken om de waarde te bepalen van rekenkundige
         expressies.</p>
	 <p>als ik op de opdrachtregel "echo $[3/4]" opgaf, zou het 0
         retourneren omdat bash alleen integers gebruikt bij beantwoording.
	 Als je "echo 3/4|bc -l" opgaf, zou het op juiste wijze 0.75
         retourneren.</p>
    </sect1>

    <sect1><heading>Bash zoeken</heading>
        <p> UIt een bericht van mike (zie Met dank aan) </p>
        <p> je gebruikt altijd #!/bin/bash .. je zou wellicht een voorbeeld</p>
        <p> kunnen geven van waar bash is te vinden.</p>
        <p> de voorkeur is 'locate bash', maar niet op alle computers is</p>
        <p> locate ge&euml;nstalleerd.</p>
        <p> `find ./ -name bash' vanaf de rootdir zal gewoonlijk wel werken.</p>
        <p> Aanbevolen te doorzoeken locaties:</p>
        <p>         ls -l /bin/bash</p>
        <p>         ls -l /sbin/bash</p>
        <p>         ls -l /usr/local/bin/bash</p>
        <p>         ls -l /usr/bin/bash</p>
        <p>         ls -l /usr/sbin/bash</p>
        <p>         ls -l /usr/local/sbin/bash</p>
        <p> (kan zo geen andere directory's bedenken...  ik heb het voorheen</p>
        <p> meestal wel op een ander systeem op &eacute;&eacute;n van deze</p>
        <p> plaatsen kunnen vinden.</p>
	<p> Je zou ook nog 'which bash' kunnen proberen.</p>
   </sect1>

    <!-- Capturing a commands output  -->    
    <sect1><heading>De return waarde van een programma verkrijgen</heading>
<p>Onder Bash, wordt de return waarde van een programma in een speciale
variabele, genaamd $?, opgeslagen.</p>
<p>Hiermee wordt ge&iuml;llustreerd hoe de return waarde van een programma
kan worden afgevangen, waarbij ik ervan uit ga dat de directory <it>dada</it>
niet voorkomt.
	(Ook dit was een suggestie van mike)
	<tscreen><verb>
	#!/bin/bash
	cd /dada &> /dev/null
	echo rv: $?
	cd $(pwd) &> /dev/null
	echo rv: $?
	</verb> </tscreen>
    </p>
    </sect1>
 
<sect1><heading>Afvangen van de uitvoer van een opdracht</heading>
<p>Dit kleine script laat alle tabellen van alle databases zien (ervan
uitgaande dat je MySQL hebt ge&iuml;nstalleerd). Overweeg tevens het
wijzigen van de opdracht 'mysql' waarbij een geldige gebruikersnaam en
wachtwoord wordt gebruikt.
	<tscreen><verb>
	#!/bin/bash
	DBS=`mysql -uroot  -e"show databases"`
	for b in $DBS ;
	do
	        mysql -uroot -e"show tables from $b"
	done
	</verb></tscreen>
</p>
</sect1>

    <!-- Meerdere bronbestanden -->
    <sect1><heading>Meerdere bronbestanden</heading>
<p>Je kunt met de opdracht source meerdere bestanden gebruiken.</p>
         <p> __TO-DO__</p>
    </sect1>
</sect>


<!-- Tables -->
<sect>
<heading>Tabellen</heading>
    <!-- String operators -->
    <sect1>
    <heading>Stringvergelijkings operatoren</heading>
    
    <p> (1) s1 = s2</p>
    <p> (2) s1 != s2</p>
    <p> (3) s1 &lt; s2</p>
    <p> (4) s1 &gt; s2</p>
    <p> (5) -n s1 </p>
    <p> (6) -z s1 </p>
     
    <p> (1) s1 komt overeen met s2</p>
    <p> (2) s1 komt niet overeen met s2</p>
    <p> (3) __TO-DO__</p>
    <p> (4) __TO-DO__</p>
    <p> (5) s1 is niet gelijk aan null
    (bevat &eacute;&eacute;n of meer tekens)</p>
    <p> (6) s1 is null </p>

    </sect1>

	<sect1><heading>Stringvergelijking voorbeelden</heading>
	<p> Vergelijken van twee strings. 
	<tscreen><verb>
	#!/bin/bash
	S1='string'
	S2='String'
	if [ $S1=$S2 ];
	then
	        echo "S1('$S1') is niet gelijk aan S2('$S2')"
	fi
	if [ $S1=$S1 ];
	then
	        echo "S1('$S1') is gelijk aan S1('$S1')"
	fi
	</verb></tscreen>
	</p>
	<p> Ik haal hier een opmerking aan vanuit een mail ingezonden door
        Andreas Beck, verwijzend naar het gebruik van
	<it/if [ $1 = $2 ]/.
	</p>
	<p>Dit is niet zo'n goed idee, omdat als $S1 of $S2 leeg is, je een
         parse error krijgt.
	 x$1=x$2 of "$1"="$2" is beter.
</p>
	</sect1>


    <!-- Arithmetic operators -->    
    <sect1><heading>Rekenkundige operators</heading>
    <p> +</p>
    <p> -</p>
    <p> *</p>
    <p> /</p>
    <p> % (rest)</p>
    </sect1>

    <!-- Arithmetic relational operators -->    
    <sect1><heading>Rekenkundige relationele operators</heading>
    <p> -lt (&lt;) </p>
    <p> -gt (>)</p>
    <p> -le (&lt;=)</p>
    <p> -ge (&gt;=)</p>
    <p> -eq (==)</p>
    <p> -ne (!=)</p>
    <p> C programmeurs zouden de operator eenvoudigweg indelen naar
    de overeenkomstige haakjes.</p>
    </sect1>
    
<!-- Usefull commands -->
<sect1>
<heading>Handige opdrachten</heading>
<p>Deze sectie werd door Kees herschreven (zie met dank aan...)</p>
<p>Een paar van deze opdrachten zijn bijna volledige programmeertalen.
Van deze opdrachten wordt alleen de basis uitgelegd. Voor een meer 
gedetailleerde beschrijving, kun je de man pages van de opdrachten raadplegen.

<bf/sed/ (stream editor)</p>

<p> Sed is een niet interactieve editor. In plaats dat een bestand wordt
aangepast door de cursor op het scherm te verplaatsen, maak je gebruik van
een script met de sed-instructies en geef je deze als argument samen met
het te wijzigen bestand op aan sed. Je kunt sed ook als een filter beschrijven.
Laten we eens wat voorbeelden bekijken:

   	<tscreen><verb>
	$sed 's/te_vervangen/vervangen_door/g' /tmp/dummy
	</verb></tscreen>
</p>

<p> Sed vervangt de string 'te_vervangen' door de string 'vervangen_door' en
leest vanuit het /tmp/dummy bestand.
Het resultaat zal naar stdout (normaal gesproken de console) worden
gezonden, maar je kunt aan het einde van deze regel ook '> capture' toevoegen
waardoor sed de uitvoer naar het bestand 'capture' zal sturen.

	<tscreen><verb>
   	$sed 12, 18d /tmp/dummy
	</verb></tscreen>	
</p>
<p> Sed laat alle regels zien behalve de regels 12 tot 18. Het oorspronkelijke
bestand wordt door deze opdracht niet aangepast.

<bf/awk/ (manipulatie van gegevensbestanden, ophalen en verwerken van tekst)
</p>
<p>Er bestaan veel implementaties van de programmeertaal AWK
(de bekendste interpreters zijn GNU's
gawk en 'new awk' mawk.) Het principe is eenvoudig: AWK scant op een patroon,
en voor ieder overeenkomend patroon zal een actie worden uitgevoerd.
	</p>
   	<p> Wederom heb ik een dummy-bestand aangemaakt met de volgende regels:
</p>
<p> <it/"test123/</p>
<p> <it/test/</p>
<p> <it/tteesstt"/</p>

<p>
   	<tscreen><verb>
	$awk '/test/ {print}' /tmp/dummy
	</verb></tscreen></p>
   	<p> test123</p>

   	<p> test</p>
<p> Het patroon waar AWK naar zoekt, is 'test' en de actie die het uitvoert
wanneer het een regel in het bestand /tmp/dummy met de string 'test' vindt, is
`print'.

   	<tscreen><verb>
	$awk '/test/ {i=i+1} END {print i}' /tmp/dummy
	</verb></tscreen>

   	3
</p>
<p>Wanneer je naar meer patronen zoekt, kun je de tekst tussen de 
aanhalingstekens beter vervangen door '-f file.awk' zodat je alle patronen
en acties in het bestand 'file.awk' kunt plaatsen.

   	<bf/grep/ (druk regels af overeenkomend met een zoekpatroon)
</p>
<p>We hebben in de vorige hoofdstuk reeds heel wat grep opdrachten gezien,
die de regels laten zien die met een patroon overeenkomen. Maar grep kan meer.
   	<tscreen><verb>
   	$grep "zoek naar dit" /var/log/messages -c
	</verb></tscreen>
   </p>
   <p> 12</p>
<p>De string "zoek naar dit" is 12 keer in het bestand /var/log/messages
gevonden.
</p>
<p> [ok, dit voorbeeld was nep, het bestand /var/log/messages was aangepast :-)]

   <bf/wc/ (telt regels, woorden en bytes)
</p>
<p>In het volgende voorbeeld, zien we dat de uitvoer niet hetgeen is wat we
ervan verwachtte. Het dummy bestand, zoals in dit voorbeeld gebruikt, bevat
de volgende tekst:
      	<it/"bash introduction/
     	<it/ howto test file"/

   <tscreen><verb>
	$wc --words --lines --bytes /tmp/dummy
	</verb></tscreen>
</p>
   <p> 2 5 34 /tmp/dummy</p>

<p>De volgorde van de parameters doet er voor wc niet toe. Wc drukt ze altijd
in de standaardvolgorde af, dus zoals je kunt zien:
&lt;lines&gt;&lt;words&gt;&lt;bytes&gt;&lt;filename&gt;.

   <bf>sort</bf> (sorteer regels van tekstbestanden)</p>

   <p> Ditmaal bevat het dummy bestand de volgende tekst:</p>
   <p> <it/"b/</p>
   <p> <it/c/</p>
   <p> <it/a"/
   	<tscreen><verb>
	$sort /tmp/dummy
	</verb></tscreen></p>

   <p> Zo ziet de uitvoer er ongeveer uit:</p>

   <p> <it>a</it></p>
   <p> <it>b</it></p>
   <p> <it>c</it></p>

   <p> Opdrachten zouden niet zo eenvoudig moeten zijn :-)
   <bf>bc</bf> (een calculator programmeertaal)</p>

<p>Met Bc kunnen berekeningen vanaf de opdrachtregel worden gemaakt
(invoer vanuit een bestand, niet via omleiding of een pipe
maar wel vanuit een gebruikersinterface.)
Het volgende demonstreert een aantal opdrachten. Merk op dat ik gebruik
maak van de parameter -q om een welkomstbericht te voorkomen.

   	<tscreen><verb>
   $bc -q
	</verb></tscreen>
</p>
   <p> <it>1 == 5</it></p>
   <p> <it>0</it></p>
   <p> <it>0.05 == 0.05</it></p>
   <p> <it>1</it></p>
   <p> <it>5 != 5</it></p>
   <p> <it>0</it></p>
   <p> <it>2 ^ 8</it></p>
   <p> <it>256</it></p>
   <p> <it>sqrt(9)</it></p>
   <p> <it>3</it></p>
   <p> <it>while (i != 9) {</it></p>
   <p> <it>i = i + 1;</it></p>
	<p> <it>print i</it></p>
   <p> <it>}</it></p>
   <p> <it/123456789/</p>
   <p> <it/quit/

   <bf/tput/ (initialiseer een terminal of ondervraag een terminfo database)
</p>
   <p> Een kleine demonstratie van de mogelijkheden van tput:
   	<tscreen><verb>
	$tput cup 10 4
	</verb></tscreen></p>
   <p> De prompt verschijnt op (y10,x4).
   	<tscreen><verb>
	$tput reset
	</verb></tscreen></p>
   <p> Maak het scherm schoon en de prompt verschijnt op (y1,x1). 
       Merk op dat (y0,x0) de linkerbovenhoek is.
   	<tscreen><verb>
	$tput cols
	</verb></tscreen>
   <it/80/</p>
   <p> Toont het aantal mogelijke tekens in richting x.</p>
   <p> Het is zeer aan te bevelen (op z'n minst) met deze programma's bekend
       te zijn. Er zijn heel veel van deze kleine programma's die je echte
       magie op de opdrachtregel laten doen.</p>
   <p> [een aantal voorbeelden zijn overgenomen uit de man pages of FAQ's]
    </p>
    </sect1>

</sect>


<!-- Meer Scripts -->
<sect>
<heading>Meer Scripts</heading>
     <sect1><heading>
     Een opdracht toepassen voor alle bestanden in een directory.
     </heading>
      
     </sect1>
     <sect1><heading>
     Voorbeeld: Een zeer eenvoudig backupscript (iets beter)
     </heading>
	   <p>
	   <tscreen><verb>
	    #!/bin/bash          
	    SRCD="/home/"
	    TGTD="/var/backups/"
	    OF=home-$(date +%Y%m%d).tgz
	    tar -cZf $TGTD$OF $SRCD
	   </verb></tscreen> 
	   </p>
     </sect1>
     <sect1><heading>
     Bestandshernoemer</heading>
          <p>
	  <tscreen><verb>
          
             #!/bin/sh
             # renna: hernoem meerdere bestanden op basis van verscheidene
             # regels geschreven door felix hudson jan - 2000
             
             # controleer dit bestand eerst op de diverse 'modes'
             # als de eerste ($1) voorwaarde overeenkomt dan voeren we dat
             # deel van het programma uit en stoppen
             
             # controleer op de prefix voorwaarde
             if [ $1 = p ]; then
             
             # nu ontdoen we ons van de mode ($1) variabele en prefix ($2)
               prefix=$2 ; shift ; shift
             
             # een snelle controle of er bestanden werden opgegeven
             # als dit niet zo is dan kunnen we maar beter niets doen dan een
             # een aantal niet bestaande bestanden te hernoemen!!
             
               if [$1 = ]; then
                  echo "geen bestanden opgegeven"
                  exit 0
               fi
             
             # deze for loop verwerkt alle bestanden die we aan het programma
             # opgaven
             # het hernoemt per opgegeven naam
               for file in $*
                 do
                 mv ${file} $prefix$file
               done
             
             # we verlaten nu het programma
               exit 0
             fi
             
             # controle op het hernoemen van een suffix
             # de rest van dit gedeelte is vrijwel gelijk aan de vorige sectie
             # kijk alsjeblieft in die notities
             if [ $1 = s ]; then
               suffix=$2 ; shift ; shift
             
                if [$1 = ]; then
                 echo "geen bestanden opgegeven"
                exit 0
                fi
             
              for file in $*
               do
                mv ${file} $file$suffix
              done
             
              exit 0
             fi
             
             # controleer op de replacement hernoeming
             if [ $1 = r ]; then
             
               shift
             
             # ik nam deze op uit voorzorg dat er geen bestanden beschadigd
             # raken als de gebruiker niets opgeeft
             # slechts een veiligheidsmaatregel
             
               if [ $# -lt 3 ] ; then
                 echo "usage: renna r [expression] [replacement] files... "
                 exit 0
               fi
             
             # verwijder andere informatie
               OLD=$1 ; NEW=$2 ; shift ; shift
             
             # deze for loop verwerkt alle bestanden die we aan het programma
             # opgaven, het hernoemt &eacute;&eacute;n bestand tegelijkertijd
             # door gebruik te maken van het programma 'sed'
             # dit is een eenvoudig opdrachtregelprogramma dat standaardinvoer
             # verwerkt en een expressie vervangt door een opgegeven string
             # hier geven we het de bestandsnaam door (als standaardinvoer) en
             # vervangen de nodige tekst
             
               for file in $*
               do
                 new=`echo ${file} | sed s/${OLD}/${NEW}/g`
                 mv ${file} $new
               done
             exit 0
             fi
             
             # als we hier zijn aangekomen dat wil dat zeggen dat niets
             # zinnigs aan het programma werd doorgegeven, dus vertellen
             # we de gebruiker hoe het te gebruiken
             echo "Gebruik;"
             echo " renna p [prefix] files.."
             echo " renna s [suffix] files.."
             echo " renna r [expression] [replacement] files.."
             exit 0
             
             # done!
             
	  </verb></tscreen>
</p>
     </sect1>
     <sect1><heading>
     Bestandshernoemer (eenvoudig)</heading>
     <p>
     <tscreen><verb>
     #!/bin/bash
     # renames.sh
     # basis bestandshernoemer

     criteria=$1
     re_match=$2
     replace=$3
     
     for i in $( ls *$criteria* ); 
     do
         src=$i
	 tgt=$(echo $i | sed -e "s/$re_match/$replace/")
	 mv $src $tgt
     done
     </verb></tscreen>
</p>
     </sect1>
</sect>

<sect>
<heading>Wanneer er iets niet goed gaat (debuggen)</heading>
     <sect1><heading>
     Manieren om BASH aan te roepen</heading>
          <p>Aardig om te doen is het volgende op de eerste regel toe te voegen
	  <tscreen><verb>
	  #!/bin/bash -x
	  </verb></tscreen></p>
	  <p>Hierdoor zal wat interessante uitvoer worden geproduceerd</p>
     </sect1>
</sect>

<sect>
<heading>Over het document</heading>
     <p>Geef me gerust je aanbevelingen/correcties, of wat je dan ook 
     interessant vindt om in dit document terug te vinden. Ik zal het
     zo spoedig mogelijk bijwerken.</p>

     <sect1>
<heading>(geen) garantie</heading>
          <p>Dit document wordt zonder enige garantie geleverd.</p>
     </sect1>

<sect1><heading>Vertalingen</heading>
     	<p> Italiaans: door William Ghelfi (wizzy at tiscalinet.it) 
     		<htmlurl name="is hier" url="http://web.tiscalinet.it/penguin_rules">
	</p>
     	<p> Frans: door Laurent Martelli 
		<htmlurl name="ontbreekt" url="http://"></p>
	<p> 
	Koreaans: Minseok Park 
		<htmlurl url="http://kldp.org" name="http://kldp.org"></p>
	<p> 
	Koreaans: Chun Hye Jin 
		<htmlurl url="" name="unknown"></p>
	<p> Spaans: onbekend 
		<htmlurl url="http://www.insflug.org" name="http://www.insflug.org"></p>
     <p> Ik denk dat er meer vertalingen zijn, maar heb daar geen informatie
     over, mail het alsjeblieft naar me als je hier informatie over hebt, zodat
     ik deze sectie kan bijwerken.</p>
     </sect1>

     <sect1>
<heading>Met dank aan</heading>
     <p>
     <itemize>
         <item>Mensen die dit document naar andere talen vertaalde (vorige
         sectie).</item>
         <item> Nathan Hurst voor het opsturen van heel wat correcties.</item>
	 <item> Jon Abbott voor het opsturen van opmerkingen over het
         berekenen van de waarde van rekenkundige expressies.</item>
	 <item> Felix Hudson voor het schrijven van het <it>renna</it>
         script</item>
         <item>Kees van den Broek (voor het opsturen van de vele correcties,
         het herschrijven van de sectie handige opdrachten)</item>
         <item>Mike (pink) deed een aantal suggesties betreft het lokaliseren
         van bash en het testen van bestanden</item>
        <item>Fiesh deed een aardige suggestie over de sectie loops</item>
        <item>Lion raadde aan melding te maken van een gebruikelijke
        foutmelding (./hello.sh: Command not found).</item>
       <item>Andreas Beck voor verscheidene correcties en opmerkingen</item>
     </itemize></p>
     </sect1>

	<sect1><heading>Historie</heading>
	<p> Nieuwe vertalingen opgenomen en kleine correcties aangebracht.</p>
	<p> De sectie handige opdrachten herschreven door Kees.</p>
	<p> Meer correcties en suggesties opgenomen.</p>
	<p> Voorbeelden toegevoegd over het vergelijken van strings.</p>
	<p> v0.8 de versie gedropt, ik denk dat de datum voldoende is.</p>
	<p> v0.7 Meer correcties en een aantal oude TO-DO secties geschreven.</p>
	<p> v0.6 Kleine correcties.</p>
	<p> v0.5 De sectie over omleiding toegevoegd.</p>
	<p> v0.4 verdween van zijn lokatie vanwegen mijn ex-baas en dit
         document vond een nieuwe plaats op de juiste url: www.linuxdoc.org.</p>
	<p> voorgaand: Ik weet het niet meer en maakte geen gebruik van rcs of
         cvs :(</p>
	</sect1>

     <sect1>
<heading>Meer bronnen</heading>

<p> Introductie bash (onder BE)
<htmlurl url="http://org.laol.net/lamug/beforever/bashtut.htm"
name="http://org.laol.net/lamug/beforever/bashtut.htm"></p>
<p> Bourne Shell Programming 
http://207.213.123.70/book/ </p>
     </sect1>
</sect>

</article>
</linuxdoc>