abonnement Unibet Coolblue Bitvavo
pi_56019425
Welkom in het centrale shell scripting topic.

Als je vragen hebt over shell scripting, dan zit je hier goed. Hier zitten idioten die verstand denken te hebben van shell scripting en je helpen om leuke nifty scriptjes te maken in de unix shell.

Mocht je een probleem hebben met je code, post deze dan even. We kunnen anders niet zien wat je precies aan het doen bent.

Nieuw met shell scripting?
Voor mensen die nieuw zijn in shell scripting, die raad ik aan om de introductie te lezen en de bash tutorial eens door te lezen. Als je wilt beginnen maakt het eigenlijk niet uit welke shell je wilt gebruiken, bash, zsh, ksh, csh, etc, etc, ze doen allemaal hetzelfde namelijk, je interface op de commandline zijn. Als je begint is het handig om bash te leren, aangezien het zeer goede documentatie heeft. Maar de andere shells worden ook actief gebruikt. In het kort, pick any, en maak daarna de eventuele overstap naar een andere shell (altijd leuk om een andere shell te leren ).

* Shell HOWTO in het Nederlands
* Een intro in shell scripting (bash)

Het portable maken van scripts
Als je een script portable maakt moet je rekening houden dat je niet altijd overal de GNU versies van verschillende applicaties hebt, dat betekend dus dat je bijvoorbeeld `sed -i' niet kan uitvoeren, en dus een andere manier hiervoor moet vinden.
Ook kan het inhouden dat je code onder andere shell talen komt te draaien. Houd hier rekening mee in je code. Op Solaris bijvoorbeeld kan je in een script die /bin/sh aanroept geen bash specifieke functies aanroepen, of syntax gebruiken. Solaris gebruikt in tegenstelling tot Linux de echte born shell. Over Solaris gesproken (en andere distro's), implementaties van sommige functies heten anders (truss en strace, tcpdump en snoop bijvoorbeeld) of hebben een andere parameters. Maar voor vragen daarover kan je in [Linux/Unix] [/Gurus/helpen/newbies]$ ./deel zoveel topic terecht (de link wijst overigens naar de wiki, daar staat namelijk de correcte URL naar het laatste topic).

Welke shell gebruik ik nou?

Welke shell je gebruikt staat in het /etc/passwd bestand. Er is een omgevings variabele SHELL die aangeeft welke shell in het wachtwoordbestand staat. Om deze variabele op te vragen moet je hetvolgende doen.

1
2
3
4
5
echo $SHELL
# Of
env | grep SHELL
# en ter overbodigheid
grep username /etc/passwd | awk -F\/ '{print $NF}'


Dit is echter geen garantie dat je ook daadwerkelijk de shell draait waar je op dat moment mee werkt. Kijk maar:

1
2
3
4
#zsh is mijn standaard shell
$ bash
$ echo $SHELL
/bin/zsh


Om er dan achter te komen welke shell je echt draait, kan je dit uitvoeren:
1echo `ps -p $$` 


Tips and tricks
Ergens verstopt (lees, op dit moment nog nergens te vinden) in wiki staat er een handige pagina met shell functies die jou kunnen helpen. Deze zijn afkomstig uit o.a. Het linux n00bs en guru's topic, of komen uit deze topicreeks.

Meer over de shell(s)
* GNU bash
* Zeer uitgebreide bash tutorial, ook handig als referentiemateriaal
* Bash reference manual
* Bourne/Korn Shell coding conventies (OpenSolaris)
* Zsh user guide
* Alleen maar shell scripting.. (forum)

Mocht je meer vragen hebben over shell scripting, op eu.freenode.org heb je verschillende kanalen, waaronder #bash. #zsh en andere #shells zullen ook wel bestaan.

Deze OP en instructies voor nieuw topic: http://wiki.fok.nl/index.php/OP/DIG/centraal/bash
Mocht je een link vinden die zeker in de OP hoort, twijfel niet en zet hem erbij!

Big fucking warning
Ga nooit "leuk" zijn en mensen vertellen dat ze rm -rf /, moeten uitvoeren, dit wordt ZWAAR bestraft door de mods @hier en terecht. Voor de mensen die niet precies weten wat dit doet: rm -rf is een recursive, geforcede delete (rm == remove) actie op de root van je systeem. Mocht je als root zijn ingelogd dan verwijder je alle bestanden van je systeem en zal je snel merken dat je PC niet meer boot en je al je data kwijt bent. Mocht je een gewone user zijn en dit uitvoeren, dan heb je grote kans dat je homedir pleitte is, en andere bestanden buiten je $HOME, waar jij de eigenaar voor bent en/of group schrijfrechten voor hebt. Voer dit daarom dan ook NOOIT uit (tenzij je pijn leuk vind of als je in een virtuele omgeving zit waar dataverlies niet uitmaakt). Als we een post vinden waarin we dit zien, kijk er dan niet raar vanop dat je niet meer kan posten in DIG, of op heel Fok for that matter. U bent gewaarschuwd!

[ Bericht 8% gewijzigd door slacker_nl op 14-01-2008 18:04:05 ]
In theory there is no difference between theory and practice. In practice there is.
  maandag 14 januari 2008 @ 11:48:51 #2
65490 whoops
Home is where the heart is...
pi_56019977
1
2
3
4
5
6
7
#!/bin/bash
CHARS=(t v p)
for C in ${CHARS[@]}
do
    echo -n $C
done
echo ''


In the beginning, the universe was created. This made a lot of people very angry and has been widely regarded as a bad move.
  maandag 14 januari 2008 @ 12:11:53 #3
126003 Daniel1976
de omnibus dubitandum
pi_56020533
-edit-

[ Bericht 83% gewijzigd door Sander op 14-01-2008 12:52:19 ]
  maandag 14 januari 2008 @ 12:12:20 #4
126003 Daniel1976
de omnibus dubitandum
pi_56020542
--

[ Bericht 93% gewijzigd door Sander op 14-01-2008 16:06:55 ]
  maandag 14 januari 2008 @ 12:14:36 #5
17137 Sander
Nerds do it rarely
pi_56020595
Dat kan je je postrechten kosten Daniel. Zeg maar voor altijd.
  maandag 14 januari 2008 @ 12:51:17 #6
65490 whoops
Home is where the heart is...
pi_56021488
quote:
Op maandag 14 januari 2008 12:11 schreef Daniel1976 het volgende:
apt-get install humor?
In the beginning, the universe was created. This made a lot of people very angry and has been widely regarded as a bad move.
pi_56021547
quote:
Op maandag 14 januari 2008 12:14 schreef Slarioux het volgende:
Dat kan je je postrechten kosten Daniel. Zeg maar voor altijd.
Daarbij zijn dat commando's die zo ontzettend zielig zijn om te roepen in dit soort topics.

Interessant topic, deze reactie tevens als TVP.
The past is what made you, but the future is what you're gonna make!
pi_56021584
quote:
Op maandag 14 januari 2008 12:14 schreef Slarioux het volgende:
Dat kan je je postrechten kosten Daniel. Zeg maar voor altijd.
nee, dit kost je postrechten:

DUS NIET UITVOEREN APEN!!

[ Bericht 1% gewijzigd door Sander op 14-01-2008 13:14:04 (niet doen) ]
In theory there is no difference between theory and practice. In practice there is.
  maandag 14 januari 2008 @ 15:06:44 #9
84926 WyriHaximus
Release the hounds smithers!
pi_56024615
Zo ook maar ff een TVPtje maken .
phluphy for president!
  maandag 14 januari 2008 @ 15:46:47 #10
187069 slacker_nl
Sicko pur sang
pi_56025420
quote:
Op maandag 14 januari 2008 12:54 schreef slacker_nl het volgende:
nee, dit kost je postrechten:
mietje slar
In theory there is no difference between theory and practice. In practice there is.
pi_56072494
quote:
Op maandag 14 januari 2008 11:48 schreef whoops het volgende:

[ code verwijderd ]

Wat doet 't ofzo? Ik ken niks van code dus zou wel graag weten wat 't is voor ik 't eens uitprobeer
  woensdag 16 januari 2008 @ 13:57:51 #12
65490 whoops
Home is where the heart is...
pi_56072601
quote:
Op woensdag 16 januari 2008 13:52 schreef tony_clifton- het volgende:

[..]

Wat doet 't ofzo? Ik ken niks van code dus zou wel graag weten wat 't is voor ik 't eens uitprobeer
Deze code print de letters TVP op je console.

Om dit de draaien moet je die code in een bestand opslaan (bijvoorbeeld filename.sh), dan met de terminal naar de directory waar het in staat en dan 'chmod +x filename.sh', en uitvoeren door ./filename.sh uit te voeren.
In the beginning, the universe was created. This made a lot of people very angry and has been widely regarded as a bad move.
pi_56073096
Ah k
ingewikkeld!
  woensdag 16 januari 2008 @ 16:06:51 #14
187069 slacker_nl
Sicko pur sang
pi_56076030
quote:
Op woensdag 16 januari 2008 13:57 schreef whoops het volgende:

[..]

Deze code print de letters TVP op je console. :)

Om dit de draaien moet je die code in een bestand opslaan (bijvoorbeeld filename.sh), dan met de terminal naar de directory waar het in staat en dan 'chmod +x filename.sh', en uitvoeren door ./filename.sh uit te voeren.
Niet perse natuurlijk, deze code kan je ook gewoon in terminal inkloppen en dan moet het ook werken. Maar in een file is het idd makkelijker, vooral als je moet gaan editten :)

Doe dit maar eens in een terminal:

enter() { echo "Enter the shell" }

en dan `which enter'

1
2
3
4
5
6
7
8
16:03 pts/9 0 wesleys@eniac:/home/wesleys$ enter() { echo "Enter the shell" }
16:03 pts/9 0 wesleys@eniac:/home/wesleys$ which enter
enter () {
        echo "Enter the shell"
}
16:03 pts/9 0 wesleys@eniac:/home/wesleys$ enter
Enter the shell
16:03 pts/9 0 wesleys@eniac:/home/wesleys$
In theory there is no difference between theory and practice. In practice there is.
  donderdag 17 januari 2008 @ 12:48:54 #15
65490 whoops
Home is where the heart is...
pi_56100073
quote:
Op woensdag 16 januari 2008 14:17 schreef tony_clifton- het volgende:
Ah k
ingewikkeld!
De makkelijkste manier om dit te doen is overigens zo:

echo TVP

maar ik vond het leuk om een array met letters te maken, en deze 1 voor 1 uit te spugen.
In the beginning, the universe was created. This made a lot of people very angry and has been widely regarded as a bad move.
pi_56145338
even een tvp want dit is verdomdig handig.
pi_56705298
Een todo manager volledig in bash geschreven. Zie filmpje op de site voor de werking ervan. Het script zelf zit vol met sed commando's. Dus als je wilt debuggen, enjoy

http://todotxt.com/library/todo.sh/
In theory there is no difference between theory and practice. In practice there is.
  woensdag 18 juni 2008 @ 22:48:16 #18
65490 whoops
Home is where the heart is...
pi_59503393
Bashers!

Ik heb het volgende stuk 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
26
27
28
29
30
31
32
33
34
35
36
37
#!/bin/bash

# Define backtitle
BACKTITLE="Nice message you got here!"

# Define header text
HEADER="This text acts like a header!"

# Define box format, Height, Width, List Height
SIZE_H=20
SIZE_W=50
SIZE_L=30

dialog --backtitle "$BACKTITLE" --checklist "$HEADER" $SIZE_H $SIZE_W $SIZE_L \
      "Choice 1" "Description One!"       ON  \
      "Choice 2" "Second Description!"    ON  \
      "Choice 3" "Third and Last!"       OFF \
      2> /tmp/checklist.tmp.$$

retval=$?

choice=`cat /tmp/checklist.tmp.$$`
rm -f /tmp/checklist.tmp.$$

case $retval in
  0)
    if [ -n "$choice" ]
    then
        echo "You chose: $choice"
    else
        echo "Can't choose?"
    fi;; 
  1)
    echo "Cancel pressed.";;
  255)
    echo "ESC pressed.";;
esac


Deze code print een lijst met keuzes d.m.v. Dialog. Dit werkt prima zo.

Ik zou echter graag de opties variabel willen maken, en dit lukt me niet. Ik heb al geprobeerd om de opties in een variabele te zetten, en deze als parameter van het dialog commando mee te geven, maar dat levert niet het gewenste resultaat op...

Anyone any clues?
In the beginning, the universe was created. This made a lot of people very angry and has been widely regarded as a bad move.
  donderdag 19 juni 2008 @ 01:21:34 #19
187069 slacker_nl
Sicko pur sang
pi_59507613
Ff dit aanpassen in je voorbeeld, anders kan ik die checklist dialog niet maken..

1
2
3
4
# Define box format, Height, Width, List Height
SIZE_H=20
SIZE_W=50
SIZE_L=3
In theory there is no difference between theory and practice. In practice there is.
  donderdag 19 juni 2008 @ 01:41:55 #20
187069 slacker_nl
Sicko pur sang
pi_59507810
Gebruik van arrays :)

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
#!/bin/bash

# Define backtitle
BACKTITLE="'Nice message you got here!'"

# Define header text
HEADER="'This text acts like a header!'"

# Define box format, Height, Width, List Height
SIZE_H=20
SIZE_W=50
#SIZE_L=3

choices[0]="'Choice 1' 'Description one!' ON"
choices[1]="'Choice 2' 'Description two!' ON"
choices[2]="'Choice 3' 'Description three!' OFF"
choices[3]="'Choice 4' 'Description four!' ON"
choices[4]="'Choice 5' 'Description five!' ON"

SIZE_L=${#choices[@]}

for ((a=0; a < SIZE_L ; a++)); do
    line="$line ${choices[$a]}"
done

choice=$(eval dialog --stdout --backtitle $BACKTITLE --checklist $HEADER $SIZE_H $SIZE_W $SIZE_L $line);

retval=$?

case $retval in
  0)
    if [ -n "$choice" ]
    then
        echo "You chose: $choice"
    else
        echo "Can't choose?"
    fi;;
  1)
    echo "Cancel pressed.";;
  255)
    echo "ESC pressed.";;
esac
In theory there is no difference between theory and practice. In practice there is.
  donderdag 19 juni 2008 @ 09:58:42 #21
65490 whoops
Home is where the heart is...
pi_59510892
Thanks dude, hier kan ik zeker wel wat mee...
In the beginning, the universe was created. This made a lot of people very angry and has been widely regarded as a bad move.
  dinsdag 24 juni 2008 @ 18:45:42 #22
65490 whoops
Home is where the heart is...
pi_59657297
Ik heb 2 vragen.

1: is er een makkelijkere manier om $i met 1 op te hogen?

1i=`echo $((i+1))`


2: In onderstaande code wil ik een dot-file uit m'n homedir inlezen, ik kan deze waarde echter niet variabel maken. Hoe krijg ik dat voor elkaar?

1
2
3
4
5
6
7
8
9
10
#!/bin/bash

CONFIG_FILE_A='/home/whoops/.server-control'
CONFIG_FILE_B='~/.server-control'

echo $CONFIG_FILE_A
echo $CONFIG_FILE_B

if [ -f "$CONFIG_FILE_A" ]; then echo "A exists"; fi
if [ -f "$CONFIG_FILE_B" ]; then echo "B exists"; fi
In the beginning, the universe was created. This made a lot of people very angry and has been widely regarded as a bad move.
  dinsdag 24 juni 2008 @ 19:24:09 #23
187069 slacker_nl
Sicko pur sang
pi_59658032
quote:
Op dinsdag 24 juni 2008 18:45 schreef whoops het volgende:
Ik heb 2 vragen.

1: is er een makkelijkere manier om $i met 1 op te hogen?
[ code verwijderd ]
Je haalt nu twee dingen door elkaar;

i=`expr $i + 1`

en

i=$((i + 1))

Die echo is niet noodzakelijk in beide gevallen.
quote:
2: In onderstaande code wil ik een dot-file uit m'n homedir inlezen, ik kan deze waarde echter niet variabel maken. Hoe krijg ik dat voor elkaar?

[ code verwijderd ]
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash

CONFIG_FILE_A="$HOME/.env.local"
CONFIG_FILE_B="~/.env.local"

for i in $CONFIG_FILE_A $CONFIG_FILE_B ; do
    if [ -f "$i" ]; then
        echo "'$i' exists";
        # Pick any
        . $i 
        source $i 
    fi
done


B pakt ie niet, maar dat komt wellicht omdat ie tijdens de test geen ~ expand naar je homedir, makkelijke workaround is $HOME gebruiken.. Zoals dus bij A gebeurd.
In theory there is no difference between theory and practice. In practice there is.
  dinsdag 24 juni 2008 @ 19:44:17 #24
147503 Iblis
aequat omnis cinis
pi_59658469
quote:
Op donderdag 19 juni 2008 01:41 schreef slacker_nl het volgende:
Gebruik van arrays
[ code verwijderd ]
Dit is overigens heel erg niet-portable naar ‘sh’ op deze manier. Als je een shell-script moet maken dat onder sh werkt, kun je dit niet gebruiken (daar heb je andere trucs voor, met eval, maar daar begin ik liever niet over.)
Daher iſt die Aufgabe nicht ſowohl, zu ſehn was noch Keiner geſehn hat, als, bei Dem, was Jeder ſieht, zu denken was noch Keiner gedacht hat.
  dinsdag 24 juni 2008 @ 19:47:11 #25
187069 slacker_nl
Sicko pur sang
pi_59658536
quote:
Op dinsdag 24 juni 2008 19:44 schreef Iblis het volgende:

[..]

Dit is overigens heel erg niet-portable naar ‘sh’ op deze manier. Als je een shell-script moet maken dat onder sh werkt, kun je dit niet gebruiken (daar heb je andere trucs voor, met eval, maar daar begin ik liever niet over.)
Nu weet ik dat whoops 99,9% bash code schrijft, en ik weet ook dat ie in 99,99% geen sh compatible code nodig heeft

Maar hoe zou je dit, voor de lol, in sh compatibel code willen doen dan?

[ Bericht 5% gewijzigd door slacker_nl op 24-06-2008 19:56:14 ]
In theory there is no difference between theory and practice. In practice there is.
  dinsdag 24 juni 2008 @ 20:31:53 #26
65490 whoops
Home is where the heart is...
pi_59659571
quote:
Op dinsdag 24 juni 2008 19:24 schreef slacker_nl het volgende:
i=$((i + 1))
quote:
$HOME gebruiken
Dit waren degene die ik zocht, thanks slack...
In the beginning, the universe was created. This made a lot of people very angry and has been widely regarded as a bad move.
  dinsdag 24 juni 2008 @ 20:47:57 #27
147503 Iblis
aequat omnis cinis
pi_59659992
quote:
Op dinsdag 24 juni 2008 19:47 schreef slacker_nl het volgende:
Maar hoe zou je dit, voor de lol, in sh compatibel code willen doen dan?
Je moet dan ‘eval’ gebruiken. eval is een built-in commando dat de argumenten evalueert als waren ze een string in een shell-script.

B.v.

1
2
3
foo=bar
bar=baz
eval echo \$$foo


De eerste twee regels zijn duidelijk, de derde werkt als volgt: eerst worden de argumenten van het commando ‘eval’ geëvalueerd, dus dat wordt in feite:

1eval echo $bar


En dan wordt ‘echo $bar’ geëvalueerd, wat ‘baz’ levert. Zo gaat het ook met je arrays:

1
2
3
4
5
6
7
foo0="foo zero"
foo1="foo one"
foo2="foo two"
foo3="foo three"
for i in 0 1 2 3; do
        eval echo \$foo$i;
done;


Dit kan heel traag worden als je b.v. meerdere indices gebruikt, het eval-commando is namelijk vrij traag.
Daher iſt die Aufgabe nicht ſowohl, zu ſehn was noch Keiner geſehn hat, als, bei Dem, was Jeder ſieht, zu denken was noch Keiner gedacht hat.
  dinsdag 24 juni 2008 @ 22:46:41 #28
65490 whoops
Home is where the heart is...
pi_59663606
quote:
Op dinsdag 24 juni 2008 20:47 schreef Iblis het volgende:

[..]

Je moet dan ‘eval’ gebruiken. eval is een built-in commando dat de argumenten evalueert als waren ze een string in een shell-script.

B.v.
[ code verwijderd ]

De eerste twee regels zijn duidelijk, de derde werkt als volgt: eerst worden de argumenten van het commando ‘eval’ geëvalueerd, dus dat wordt in feite:
[ code verwijderd ]

En dan wordt ‘echo $bar’ geëvalueerd, wat ‘baz’ levert. Zo gaat het ook met je arrays:
[ code verwijderd ]

Dit kan heel traag worden als je b.v. meerdere indices gebruikt, het eval-commando is namelijk vrij traag.
Het gebruiken van eval doet slacker ook al in zijn antwoord op mijn vraag hierboven...

Vanuit php heb ik trouwens altijd geleerd eval==evil en op zich denk ik dat ook wel... Toch gebruik ik het om mijn array mooi in dialog te krijgen. Als jij daar nog een manier zonder eval voor weet hou ik me aanbevolen...

De scripts die ik schrijf mogen inderdaad wel puur bash zijn, over het algemeen bouw ik ze voor een eigen gebruik, hoewel het het mooiste is om standaard te zijn...
In the beginning, the universe was created. This made a lot of people very angry and has been widely regarded as a bad move.
pi_59666911
quote:
Op dinsdag 24 juni 2008 20:47 schreef Iblis het volgende:
Dit kan heel traag worden als je b.v. meerdere indices gebruikt, het eval-commando is namelijk vrij traag.
Ik had al het vermoeden dat je deze methode zou gaan gebruiken. Heb hem ook overwogen in eerste instantie, maar vond de array feature veel handiger Je kan makkelijker opties toevoegen, tenminste, je hoeft niet ook nog eens je for loop te definieren.

Maar we zijn stom bezig.... Terwijl ik bezig was om te kijken welke manier nou sneller was kwam ik op de uiteindelijke oplossing. Een soort van array push simuleren in bash. sh is twijfelachtig, $((i + i)) wordt volgens mij niet ondersteund.

1
2
3
4
5
6
7
8
9
10
function add_choice() {
    if [ -n "$1" ] ; then
        CHOICES="$CHOICES $1"
        LIMIT=$((LIMIT + 1))
        #LIMIT=`expr $LIMIT + 1`
    else
        CHOICES=""
        LIMIT=0
    fi
}


test_bash
real 0m0.005s
user 0m0.004s
sys 0m0.000s

test_sh
real 0m0.048s (schommelt tussen .024 - .050 bij herhaaldelijk aanroepen)
user 0m0.008s
sys 0m0.020s

test_choice
real 0m0.006s
user 0m0.008s
sys 0m0.000s

test_choice - met expr (schommelt tussen .045 - .070)
real 0m0.044s
user 0m0.036s
sys 0m0.008s

test_choice - sh compat
real 0m0.028s (schommelt tussen .014 - .030)
user 0m0.012s
sys 0m0.004s


De code
  donderdag 28 augustus 2008 @ 11:37:51 #30
74548 Jo0Lz
Lick the box!
pi_61187918
Centraal.
Yes we can! | I didn't fail, it's just postponed success.
pi_61190721
quote:
Op donderdag 28 augustus 2008 11:37 schreef Jo0Lz het volgende:
Centraal.
Goeie zaak, want ik had dit topic nog niet eerder opgemerkt!
quote:
Op maandag 14 januari 2008 11:22 schreef slacker_nl het volgende:
Big fucking warning
Ga nooit "leuk" zijn en mensen vertellen dat ze rm -rf /, moeten uitvoeren, dit wordt ZWAAR bestraft door de mods @hier en terecht. Voor de mensen die niet precies weten wat dit doet: rm -rf is een recursive, geforcede delete (rm == remove) actie op de root van je systeem. Mocht je als root zijn ingelogd dan verwijder je alle bestanden van je systeem en zal je snel merken dat je PC niet meer boot en je al je data kwijt bent. Mocht je een gewone user zijn en dit uitvoeren, dan heb je grote kans dat je homedir pleitte is, en andere bestanden buiten je $HOME, waar jij de eigenaar voor bent en/of group schrijfrechten voor hebt. Voer dit daarom dan ook NOOIT uit (tenzij je pijn leuk vind of als je in een virtuele omgeving zit waar dataverlies niet uitmaakt). Als we een post vinden waarin we dit zien, kijk er dan niet raar vanop dat je niet meer kan posten in DIG, of op heel Fok for that matter. U bent gewaarschuwd!
Het kan ook erger (spreek ik uit ervaring... 8)7 8)7 ):
1cd /tmp; rm -rf .*

Ooit wou ik alle files en directories die met een PUNT beginnen in /tmp opruimen (dit zijn de directories die o.a. X achterlaat). Echter, hierbij zag ik over het hoofd dat ".." op deze manier ook wordt meegenomen, en vanaf /tmp is ".." gelijk aan / ... Na enkele seconden viel het kwartje, omdat de delete-actie wel erg lang duurde, en heb ik CTRL-C gedaan. M'n userdata was nog veilig, maar m'n OS kon ik opnieuw installeren (en nee, m'n OS backup ik niet).
Ondertussen is "rm .*" zo slim om te zeggen dat-ie . en .. negeert :)
Moraal van het verhaal: Unix/Linux doet precies wat je zegt, maar pas altijd op wat je zegt :D
censuur :O
  donderdag 28 augustus 2008 @ 13:39:48 #32
147503 Iblis
aequat omnis cinis
pi_61191184
quote:
Op donderdag 28 augustus 2008 13:22 schreef RemcoDelft het volgende:
Ondertussen is "rm .*" zo slim om te zeggen dat-ie . en .. negeert
Moraal van het verhaal: Unix/Linux doet precies wat je zegt, maar pas altijd op wat je zegt
rm zelf doet niets met ‘.*’, het is de shell die zo’n pattern matcht en vervang door een lijst van bestanden die eraan voldoen. De Kornshell laat . en .. niet matchen op .*, bash echter soms wel, afhankelijk van de waarde van $GLOBIGNORE. Als je rm -rf .. intypt zal het nog steeds misgaan.

Bij zulke zaken is het dus goed om uit te zoeken wat de precieze semantiek van je shell is!
Daher iſt die Aufgabe nicht ſowohl, zu ſehn was noch Keiner geſehn hat, als, bei Dem, was Jeder ſieht, zu denken was noch Keiner gedacht hat.
pi_61841228
Ik ben inmiddels weer vrolijk aan het bashen geslagen, ik zoek een manier om te kijken of ik in een string evenveel { en }; heb. Nu dacht ik, als ik nou de regex gebruik die ingebouwd zit in bash.

1
2
3
4
5
6
7
string="zone "asdf.asdf" {type master;file "/etc/bind/zones/asdf.asdf.db";allow-transfer{none;};};"
regex="};"
if [[ "$string" =~ $regex ]]; then
     echo "Jay, ik heb ${#BASH_REMATCH[*]} keer een }; gevonden";
else
     echo "He verdorie, niets..";
fi


echter komt hier altijd 1 uit.

Toen ben ik verder gaan zoeken, en toen had ik zoiets als dit
1
2
3
#get number of { and substract one.
nr=`echo "$string" | tr "{" "\n" | wc -l`
let nr=nr-1;


Dit werkt voor het { gedeelte van de twee. Voor de }; echter niet, ik denk dat dit komt omdat tr een match heeft per character in plaats van een tekenreeks.

Enig idee hoe ik of het }; gedeelte kan uitvissen, of hoe ik dit anders aan zou moeten pakken?
  dinsdag 23 september 2008 @ 10:07:12 #34
65490 whoops
Home is where the heart is...
pi_61844711
Volgens mij werkt je methode met tr en wc wel hoor.

1
2
3
4
5
$ string="en { dat { is { een { en { dat { is { twee en } dat } is } drie } en } dat } is } vier "
$ echo "$string" | tr "}" "\n" | wc -l
8
$ echo "$string" | tr "{" "\n" | wc -l
8


Ik zou overigens niet weten of het efficienter kan.
In the beginning, the universe was created. This made a lot of people very angry and has been widely regarded as a bad move.
pi_61848689
quote:
Op dinsdag 23 september 2008 10:07 schreef whoops het volgende:
Volgens mij werkt je methode met tr en wc wel hoor.
[ code verwijderd ]

Ik zou overigens niet weten of het efficienter kan.
Klopt, echter is de sluit "tag" }; dus inclusief de ;

Als de ; op een volgende regel staat, moet deze meegenomen worden. Dus moet eerst de volgende regel ingelezen worden, waarna hij pas compleet is. Dus hij moet echt gematcht worden op "};"

  donderdag 25 september 2008 @ 08:23:23 #36
147503 Iblis
aequat omnis cinis
pi_61896354
In principe kun je met regexpen niet wat je hiermee wilt. Een regexp kan niet echt ‘tellen’ en niet kijken of haakjes gebalanceerd zijn. Je kunt het proberen, maar als je de string '{a{b}c{d}e}' hebt dan zal een regexp voor '{.*}' matchen op de gehele string als deze greedy is, of op '{a{b}' als deze lazy is. In het eerste geval zou je weer kunnen substring matchen, maar dan heb je eenzelfde probleem, omdat dan de match {b}c{d} wordt. (En een substring match op b}c{d niet gaat werken.)

Met veel kunst en vliegwerk is hier wel omheen te werken. De oplossing met ‘tr’ heeft een beetje een probleem dat het foute input als '}}{{' er niet uit kan halen. Ik weet niet of je dat wilt, maar anders is dit een probleem. Het makkelijkste is, als je het echt foutloos wilt doen, een klein perl of awk scriptje te schrijven dat de input simpelweg karakter voor karakter langsgaat en bij elke { de teller ophoogt, en bij elke } verlaagt. Als je teller < 0 komt, heb je te veel }, is deze > 0 bij het eind van de input heb je te veel { en is deze 0, dan zijn ze in balans. Verder kun je dus, als deze 0 is, de input afscannen naar ';'.

Weet je zeker dat de haakjes wel in balans zijn, dan zou je het volgende kunnen proberen:

1
2
3
4
5
6
7
8
9
string="en { dat { is { een {; en { dat { is { twee en } dat } is } drie } en } dat } is \n}\n; vier "
nstring=$(echo $string | tr -d -C '{};')
leftcount=$(echo $nstring | grep -o '{' | wc -l)
rightcount=$(echo $nstring | grep -o '}' | wc -l)
if echo "$nstring" | grep -q '};$' &&  test $leftcount -eq $rightcount; then
        echo 'bingo';
else
        echo 'jammer'
fi;


Eerst haal ik dus alle zooi uit de string behalve {, } en ; – ook de '\n's zijn dan weg. Dan tel ik linker en rechter haakjes (aannemende dat ze al in balans zijn). En dan moet de string met '};' eindigen.
Daher iſt die Aufgabe nicht ſowohl, zu ſehn was noch Keiner geſehn hat, als, bei Dem, was Jeder ſieht, zu denken was noch Keiner gedacht hat.
pi_61903539
Hier ga ik morgen even mee aan de slag, even rondspelen met verschillende input combinaties, misschien werkt het, maar waarschijnlijk zit er nog een mogelijkheid in dat een blok (dus wat tussen de { en de }; zit) niet afgesloten kan zijn geweest.

Maar opzich maakt dat niet heel erg veel uit, aangezien BIND zelf dan gaat lopen mekkeren dat de syntax niet goed is.

Bedankt voor de mogelijke oplossing. Ik ben benieuwd

p.s. PERL is geen optie, omdat dit niet aanwezig is op het systeem (en niet geinstalleerd mag/kan worden)
  donderdag 25 september 2008 @ 16:40:59 #38
147503 Iblis
aequat omnis cinis
pi_61908319
Met AWK kun je nagenoeg hetzelfde als met Perl, zij het vaak iets minder beknopt. Zie onderstaande code. BEGIN wordt uitgevoerd voordat de input wordt gelezen, END altijd nadat alle input is gelezen, en het blok ertussen voor elke regel. Hij scant dus elke regel karakter voor karakter op '}', als de haakjes uit balans zijn komt er een error. Na de laatste } moet een ';' komen. Er is één catch, de input die alleen uit ';' bestaat wordt óók goedgekeurd. Daar kun je misschien expliciet op checken.

Je runt het met awk -f 'bestand' en kunt er dan gewoon via stdin input instoppen.

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
BEGIN {
        counter = 0;
        done = 0;
}
{
        for (i = 1; i <= length($0); i++) {
                c = substr($0, i, 1);
                if (c== "{") {
                        counter++
                        done = 0;
                } else if (c == "}") {
                        if (counter == 0) {
                                print "Meer } dan { gevonden!";
                                exit 1;
                        }
                        counter--;
                } else if (c == ";" && counter == 0) {
                        done = 1;
                }
        }
}
END {
        if (counter > 0) {
                print "Enkele { zijn niet afgesloten!";
                exit 1;
        }
        if (!done) {
                print "Geen afsluitende ';' gevonden!"
                exit 1;
        }
        print "Alles in orde."
}
Daher iſt die Aufgabe nicht ſowohl, zu ſehn was noch Keiner geſehn hat, als, bei Dem, was Jeder ſieht, zu denken was noch Keiner gedacht hat.
pi_61982165
quote:
Op donderdag 25 september 2008 16:40 schreef Iblis het volgende:
Met AWK kun je nagenoeg hetzelfde als met Perl, zij het vaak iets minder beknopt. Zie onderstaande code. BEGIN wordt uitgevoerd voordat de input wordt gelezen, END altijd nadat alle input is gelezen, en het blok ertussen voor elke regel. Hij scant dus elke regel karakter voor karakter op '}', als de haakjes uit balans zijn komt er een error. Na de laatste } moet een ';' komen. Er is één catch, de input die alleen uit ';' bestaat wordt óók goedgekeurd. Daar kun je misschien expliciet op checken.

Je runt het met awk -f 'bestand' en kunt er dan gewoon via stdin input instoppen.
[ code verwijderd ]


Bedankt voor de reactie, Ik probeer de Named.Conf.Local te parsen van BIND. Hierbij is het nodig dat ik fouten probeer te voorkomen waar dit mogelijk is. Voorbeeld van invoer:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
zone "asdf.asdf" {type master;file "/etc/bind/zones/asdf.asdf.db";allow-transfer{none;};};

Maar ook:

zone "asdf.net"
{

type master;
file "/etc/bind/zones/asdf.net.db";};

   zone "asdf.com" { //some comment here
        type master;
        file "/etc/bind/zones/asdf.com.db";
        allow-transfer


        {
                none;
}

;
};


Ik zoek het eerste gedeelte op met een regular expression, waardoor ik weet waar ik moet beginnen.
Daarna (is de bedoeling) dat ik bekijk dat ik na een { ook een bijbehorende }; heb. Wanneer dit zo is, weet ik dat ik de volledige zone heb. Wanneer dit niet zo is, lees ik de volgende regel in (verwijder ik whitespaces en comments), en bekijk ik verder of ik alles heb.

Hierdoor is het dus ook zo dat de ; 2 regels later kan komen.

Op dit moment heb ik (ongeveer) hetzelfde gedaan wat jij doet in die paar regels met awk, alleen dan ook met (basic) syntax checking.

Ik moet alleen nog bekijken hoe ik een newline kan matchen met een regular expression, aangezien na een } wel een spatie en een newline kan komen, maar geen ander teken moet ik hier rekening mee houden.

Wanneer de zone file naar de bagger is, moet het script stoppen en het niet erger maken :)

Ik zie dat je met awk redelijk veel kan doen, wist niet dat er zo een uitgebreide scripttaal achter zat..
  zondag 28 september 2008 @ 21:58:12 #40
147503 Iblis
aequat omnis cinis
pi_61982321
Newlines in reguliere expressies matchen is meestal gewoon ‘\n’, maar veel tools scheiden impliciet op ‘\n’, zodat er dus nooit een ‘\n’ in je string komt. Als je dit weet echter kun je toch simpelweg (in termen van AWK) records inlezen, wat in de praktijk op regels neerkomt, en kijken of die records alleen spaties bevatten. Die records c.q. regels zelf moeten dan wel door ‘\n’ gescheiden zijn.
Daher iſt die Aufgabe nicht ſowohl, zu ſehn was noch Keiner geſehn hat, als, bei Dem, was Jeder ſieht, zu denken was noch Keiner gedacht hat.
pi_61988080
quote:
Op zondag 28 september 2008 21:58 schreef Iblis het volgende:
Newlines in reguliere expressies matchen is meestal gewoon ‘\n’, maar veel tools scheiden impliciet op ‘\n’, zodat er dus nooit een ‘\n’ in je string komt. Als je dit weet echter kun je toch simpelweg (in termen van AWK) records inlezen, wat in de praktijk op regels neerkomt, en kijken of die records alleen spaties bevatten. Die records c.q. regels zelf moeten dan wel door ‘\n’ gescheiden zijn.
Op dit moment ben ik niet zeker of het de newline character is wat zo loopt te klieren. Wanneer ik het wil echoen op het scherm, krijg ik gewoon een spatie, maar hij word niet gematcht door de \s teken. Ik zal wat meer debuggen en dan kom ik hier op terug.

Bedankt voor het meedenken iedereen
  dinsdag 23 december 2008 @ 14:22:10 #42
187069 slacker_nl
Sicko pur sang
pi_64283768
Weet iemand hoe het komt dat bash hetvolgende doet;

1
2
3
bla=$(find . -print) 
echo $bla
. ./CS01.WANA-EAS.FI.2008.048.v02.csv ./CS01.BBDD-DSL.FI.2008.018.v02.csv ./rrd.ppt


Zsh doet dit, en dit is wat ik wil:
1
2
3
4
5
6
bla=$(find . -print) 
echo $bla
.
./CS01.WANA-EAS.FI.2008.048.v02.csv
./CS01.BBDD-DSL.FI.2008.018.v02.csv
./rrd.ppt



-edit-
echo "$bla" is de oplossing...

Zie http://wooledge.org:8000/WordSplitting

[ Bericht 5% gewijzigd door slacker_nl op 23-12-2008 14:33:24 ]
In theory there is no difference between theory and practice. In practice there is.
  dinsdag 23 december 2008 @ 14:38:00 #43
29444 RemcoDelft
4 8 15 16 23 42
pi_64284449
Waarom find . -print? Doet dat niet hetzelfde als gewoon "find"?

Ik gebruik altijd zoiets, veel inzichtelijker:
for i in `find`; do echo $i; done
censuur :O
  dinsdag 23 december 2008 @ 14:41:04 #44
187069 slacker_nl
Sicko pur sang
pi_64284585
quote:
Op dinsdag 23 december 2008 14:38 schreef RemcoDelft het volgende:
Waarom find . -print? Doet dat niet hetzelfde als gewoon "find"?

Ik gebruik altijd zoiets, veel inzichtelijker:
for i in `find`; do echo $i; done
Kan ook zonder de -print. Gebruik ze beide. Maar ik hoef niet over find te loopen.

Uit de man page van find:
quote:
If no expression is present, -print will be used as the
expression. Otherwise, if the given expression does not con-
tain any of the primaries -exec, -ok or -print, the given
expression will be effectively replaced by:

( given_expression ) -print
En als niet perse sh compatible code hoeft te schrijven $() is veel sneller dan backticks.

for i in $(find . ) ; do echo $i ; done
In theory there is no difference between theory and practice. In practice there is.
  dinsdag 23 december 2008 @ 17:38:18 #45
147503 Iblis
aequat omnis cinis
pi_64291258
$() is ook gewoon POSIX. Je hebt dus sowieso een niet-POSIX shell te pakken als $() het niet doet. De vraag is in hoeverre je daar tegenwoordig nog rekening mee wilt houden.
Daher iſt die Aufgabe nicht ſowohl, zu ſehn was noch Keiner geſehn hat, als, bei Dem, was Jeder ſieht, zu denken was noch Keiner gedacht hat.
pi_64322877
Op solaris 8:

cat x.sh
#!/bin/sh

echo $(ls)

chmod +x x.sh
./x.sh
./x.sh: syntax error at line 3: `(' unexpected
In theory there is no difference between theory and practice. In practice there is.
pi_72613782
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
#!/bin/bash

TOTAL_MEM=0
TOTAL_PROC=0
DIV=$(perl -e 'print "-" x 40')

printf "%-10s %-18s %-10s\n" pid name anon_mem

echo $DIV

pgrep -lf "^ora_j"| sort -k2 | while read pid name junk ; do
    [ -z "$pid" ] && continue
    RES=$(pmap -x $pid 2>/dev/null)
    [ $? -ne 0 ] && continue
    RES=$(echo -e "$RES"  |tail -1 | awk '{NF=NF-1} {print $NF}' )
    printf "%-10d %-18s %-10d\n" $pid $name $RES
    TOTAL_MEM=$(($TOTAL_MEM + $RES))
    TOTAL_PROC=$((TOTAL_PROC +1 ))
    # Just for testing
    [ $TOTAL_PROC -eq 5 ] && break
done

TOTAL_MEM_GB=$(echo "scale = 4; ($TOTAL_MEM/1024)/1024"|bc)
echo $DIV
printf "TOTALS\n%-10s %-18s %-10s" procs "anon_mem kb" "anon_mem Gb"
echo $DIV

printf "%-10s %-18s %-10s\n" "$TOTAL_PROC" "$TOTAL_MEM" "$TOTAL_MEM_GB"


Waarom print ie niet m'n totalen uit??

Als ik
1pgrep -lf "^ora_j"| sort -k2 | while read pid name junk ; do

naar
1
2
3
for i in $(pgrep -lf "^ora_j"| sort -k2|sed -e 's/ /$/') ; do
pid=$(echo $i | cut -d\$ -f1)
name=$(echo $i | cut -d\$ -f2)


Werkt het wel... Why??
In theory there is no difference between theory and practice. In practice there is.
  donderdag 10 september 2009 @ 15:40:11 #48
147503 Iblis
aequat omnis cinis
pi_72614193
Daher iſt die Aufgabe nicht ſowohl, zu ſehn was noch Keiner geſehn hat, als, bei Dem, was Jeder ſieht, zu denken was noch Keiner gedacht hat.
  donderdag 10 september 2009 @ 15:45:45 #49
65490 whoops
Home is where the heart is...
pi_72614324
quote:
Op donderdag 10 september 2009 14:20 schreef slacker_nl het volgende:

[ code verwijderd ]

Waarom print ie niet m'n totalen uit??

Als ik
[ code verwijderd ]

naar
[ code verwijderd ]

Werkt het wel... Why??
Gebruik dan ook geen bash maar zsh ofzo...
In the beginning, the universe was created. This made a lot of people very angry and has been widely regarded as a bad move.
pi_72614724
@whoops
Spuit 11

@Iblis
Hehehe, held
In theory there is no difference between theory and practice. In practice there is.
abonnement Unibet Coolblue Bitvavo
Forum Opties
Forumhop:
Hop naar:
(afkorting, bv 'KLB')