Toon posts:

Gedeelte van shellscript herhalen

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb een simpel shellscriptje gemaakt dat de gebruiker vraagt naar een zoekterm en een bestandsnaam. Als het bestand bestaat in de huidige directory, dan drukt het script het aantal regels met de zoekterm in het bestand af. Zo niet, dan geeft het script een foutmelding.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/sh
echo Een zoekterm alstublieft.
read zoekterm
echo Een bestandsnaam alstublieft.
read bestandsnaam

test -e $bestandsnaam
if test $? = 0

then
        grep -c $zoekterm $bestandsnaam
else
        echo Dat bestand bestaat niet.
fi

Dat werkt allemaal prima. Nu wil ik dat het script zichzelf blijft herhalen (dus weer opnieuw begint met het vragen naar een zoekterm en bestandsnaam) totdat de gebruiker een bestandsnaam invoert die niet bestaat. Als dat laatste gebeurt wil ik het script laten stopen met een melding. Ik heb gezocht en geprobeerd, maar ik krijg het maar niet voor elkaar.

Het enige wat ik kan bedenken is het onderstaande, maar hierdoor blijft het script continu het aantal gevonden regels afdrukken :X

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/sh
echo Een zoekterm alstublieft.
read zoekterm
echo Een bestandsnaam alstublieft.
read bestandsnaam

test -e $bestandsnaam
while test $? = 0

do
        grep -c $zoekterm $bestandsnaam
done

echo Dat bestand bestaat niet.

Ik zie het niet meer. Ook niet na redelijk goed gezocht te hebben alhier en op Google. Wie kan me helpen?

  • urk_forever
  • Registratie: Juni 2001
  • Laatst online: 31-01 21:11
Misschien moet je je vraag om een bestandsnaam ook in de loop gooien?

Zoiets in pseudo code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
NietGevonden = False

while not NietGevonden

  echo "Geef een bestandsnaam"
  read bestandsnaam

  zoek bestand
  
  if not bestand gevonden then
    nietGevonden = True
  end if
wend

[ Voor 64% gewijzigd door urk_forever op 31-08-2007 16:10 ]

Hail to the king baby!


Verwijderd

Topicstarter
Held! Dat werkt. De pseudo-code deed mij het licht zien :+

Het uiteindelijke brouwsel:

code:
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
#!/bin/sh

nietgevonden="false"

while test $nietgevonden = "false"

do

echo "Geef een bestandsnaam"
read bestandsnaam

test -e $bestandsnaam
if test $? = "0"

then
        echo "Geef een zoekterm"
        read zoekterm
        grep -c $zoekterm $bestandsnaam
        nietgevonden="false"

else
        echo "Bestaat niet"
        nietgevonden="true"
fi
done

  • Super_ik
  • Registratie: Maart 2001
  • Laatst online: 13:39

Super_ik

haklust!

je kent deze he: http://tldp.org/LDP/abs/html/

want dit is wel een beetje raar:
test -e $bestandsnaam
if test $? = "0"
==>
if [ -e $bestandsnaam ]; then

[ Voor 19% gewijzigd door Super_ik op 31-08-2007 21:35 ]

8<------------------------------------------------------------------------------------
Als ik zo door ga haal ik m'n dood niet. | ik hou van goeie muziek


Verwijderd

Topicstarter
Dat is inderdaad wat netter. Wel bijzonder dat je bij
code:
1
test -e $bestandsnaam
alsnog dat &? nodig hebt voor een werkend script, terwijl dat bij [ -e $bestandsnaam ] niet hoeft. Het is in feite hetzelde commando als ik de manpagina van 'test' goed begrijp.

  • deadinspace
  • Registratie: Juni 2001
  • Laatst online: 13:45

deadinspace

The what goes where now?

Verwijderd schreef op zondag 02 september 2007 @ 10:28:
Dat is inderdaad wat netter. Wel bijzonder dat je bij
code:
1
test -e $bestandsnaam
alsnog dat &? nodig hebt voor een werkend script, terwijl dat bij [ -e $bestandsnaam ] niet hoeft. Het is in feite hetzelde commando als ik de manpagina van 'test' goed begrijp.
Je begrijpt het verkeerd :)

Programma's geven bij het afsluiten een zogenaamde return code terug. Dit is een klein getal in het bereik 0 - 255. De conventie is dat 0 succes betekent, en niet-nul falen. Na het uitvoeren van een programma plaatst de shell deze return code in $?.

If <programma> is een shell-constructie die de then-tak uitvoert als programma succesful was (return code 0), en de else tak als programma faalde (return code > 0).

'Test' is een programma dat een bepaalde conditie test, en 0 returnt als deze conditie waar is, en niet-nul als de conditie onwaar is.

Je originele code was:
code:
1
2
test -e $bestandsnaam
if test $? = 0

Als $bestandnaam bestaat, dan returnt die eerste test 0, dus de shell plaatst 0 in $?. Vervolgens roep je weer test aan met $? = 0. $? is 0, dus ook die test returnt 0. De 'if' ziet de 0 van die tweede test, en voert dus de then-tak uit.

Het hele punt is dat die tweede test hier helemaal niks toevoegt. Hij returnt 0 als de eerste test 0 returnde, en hij returnt niet-nul als de eerste test niet-nul returnde. Waarom dan niet 'if' laten controleren op de return code van de eerste test?

Je code kan dus beter zo geschreven worden:
code:
1
if test -e $bestandsnaam

En dan is het gebruikelijk (maar niet noodzakelijk) om [ te gebruiken in plaats van test:
code:
1
if [ -e $bestandsnaam ]

Je hebt $? dus sowieso niet nodig, of je nou test of [ gebruikt.

Je script gaat trouwens niet netjes om met een lege filename, lege zoekterm, filenames met spaties, of zoektermen met spaties. Ik had het script liever zo geschreven:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#! /bin/sh

while true
do
        echo -n "Bestandsnaam: "
        read FILE

        if ! [ -e "${FILE}" ]
        then
                echo "'${FILE}' bestaat niet."
                exit 0
        fi

        echo -n "Zoekterm: "
        read PATTERN

        RESULTS=$(grep -c "${PATTERN}" "${FILE}")
        echo "${RESULTS} resultaten."
done

  • icyx
  • Registratie: Januari 2007
  • Niet online

icyx

chown -R us ./base

Hmm, deadinspace, dat met die $? wist ik niet, bedankt voor je uitleg, kan nog wel eens van pas komen :)

When you think you’ve succeeded / but something’s missing / means you have been defeated / by greed, your weakness.


Verwijderd

Topicstarter
Heldere uitleg, bedankt :>
Pagina: 1