bash AND OR brackets vraag

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • amx
  • Registratie: December 2007
  • Laatst online: 22:42
ik heb de volgende eenvoudige test:

~/foo
~/bar

In beide bestanden staat dezelfde tekst ("Hello world")

Ik wil de volgende test uitvoeren:

[ ~/foo = ~/bar ] && echo "foo = bar"

In de constructie zijn beide variabelen gelijk, dus de AND operator && is hier toch de juiste?

Ik krijg tijdens testen alleen bij de OR operator de echo uitvoer


In boolean is het toch ook: ALS foo IS GELIJK AAN bar DAN echo foo = bar

Acties:
  • 0 Henk 'm!

  • yeadder
  • Registratie: Maart 2001
  • Niet online
Vergeef me als ik er naast zit, ik ben een beetje roestig geworden op dit gebied.

Maar && wil zeggen voer het opvolgende commando uit wanneer het eerste waar is of gelukt is.

Je zou bijvoorbeeld een commando kunnen aanroepen die voorbereidend werk doet zoals bestanden op een juiste plaats zetten en met && het volgende commando aanroepen. Wanneer de bestanden probleemloos op de juiste plek zijn gezet, wordt het twee commando pas aangeroepen.

In jouw voorbeeld / vraag kan het dus zijn dat je eerste test / commando een error/false terug geeft waardoor het tweede commando (echo) niet wordt aangeroepen. Zoals je zelf ook al aangeeft.

Op dit moment vergelijk je de "bestandsnamen" maar je wil de inhoud vergelijken. Wanneer je dit doet, zal de vergelijking waar zijn. Daarvoor kun je bijvoorbeeld "cat" gebruiken om de bestanden uit de te lezen tijdens de vergelijking. Bijvoorbeeld iets in de trant van: [ 'cat ~/foo' = 'cat ~/bar' ]. Zover mijn geheugen mij niet in de steek laat zorgt 'commando' ervoor dat het commando wordt uitgevoerd en de output wordt meegenomen.

Acties:
  • 0 Henk 'm!

  • amx
  • Registratie: December 2007
  • Laatst online: 22:42
Klopt, ik ben bezig om deze in een case constructie te zetten, en had voorheen een diff -q vergelijking, met daarbij een aparte file ertussen. Bij de test variant moet de test de inhoud vergelijken, niet de filename.
Dank :)

Acties:
  • 0 Henk 'm!

  • Demo
  • Registratie: Juni 2000
  • Laatst online: 30-09 11:31

Demo

Probleemschietende Tovenaar

yeadder schreef op woensdag 03 juli 2013 @ 10:25:
Vergeef me als ik er naast zit, ik ben een beetje roestig geworden op dit gebied.

Maar && wil zeggen voer het opvolgende commando uit wanneer het eerste waar is of gelukt is.

Je zou bijvoorbeeld een commando kunnen aanroepen die voorbereidend werk doet zoals bestanden op een juiste plaats zetten en met && het volgende commando aanroepen. Wanneer de bestanden probleemloos op de juiste plek zijn gezet, wordt het twee commando pas aangeroepen.

In jouw voorbeeld / vraag kan het dus zijn dat je eerste test / commando een error/false terug geeft waardoor het tweede commando (echo) niet wordt aangeroepen. Zoals je zelf ook al aangeeft.

Op dit moment vergelijk je de "bestandsnamen" maar je wil de inhoud vergelijken. Wanneer je dit doet, zal de vergelijking waar zijn. Daarvoor kun je bijvoorbeeld "cat" gebruiken om de bestanden uit de te lezen tijdens de vergelijking. Bijvoorbeeld iets in de trant van: [ 'cat ~/foo' = 'cat ~/bar' ]. Zover mijn geheugen mij niet in de steek laat zorgt 'commando' ervoor dat het commando wordt uitgevoerd en de output wordt meegenomen.
Je moet de ` gebruiken die op dezelfde toets zit als ~. Naast de 1. De ' en " gebruik je om 'string met spaties' te vergelijken. Maar je hebt gelijk, nu worden de bestandsnamen met elkaar vergeleken.

Unix doesn't prevent a user from doing stupid things, because that would necessarily prevent them from doing brilliant things.
while true ; do echo -n "bla" ; sleep 1 ; done


Acties:
  • 0 Henk 'm!

  • deadinspace
  • Registratie: Juni 2001
  • Laatst online: 20:04

deadinspace

The what goes where now?

amx schreef op woensdag 03 juli 2013 @ 09:58:
[ ~/foo = ~/bar ] && echo "foo = bar"

In de constructie zijn beide variabelen gelijk, dus de AND operator && is hier toch de juiste?
Ik zie geen variabelen, maar ~/foo is natuurlijk niet gelijk aan ~/bar ;)
~/foo en ~/bar zijn gewoon strings die worden vergeleken op gelijkheid, ze worden door test niet geinterpreteerd als directories waarvan de inhoud vergeleken moet worden. Als je zoiets zoekt, dan kun je waarschijnlijk beter naar diff kijken.
In boolean is het toch ook: ALS foo IS GELIJK AAN bar DAN echo foo = bar
Als je een als...dan constructie zoekt, waarom gebruik je dan geen als...dan constructie? Dat is in ieder geval beter leesbaar en begrijpbaar.
code:
1
2
3
4
if ~/foo = ~/bar
then
    echo "foo = bar"
fi
Demoniac schreef op woensdag 03 juli 2013 @ 11:01:
Je moet de ` gebruiken die op dezelfde toets zit als ~. Naast de 1. De ' en " gebruik je om 'string met spaties' te vergelijken.
Die backtick is echt de meest idiote syntax ooit; het is veel beter om $() te gebruiken, dat is veel leesbaarder en dan heb je die hele verwarring tussen ' en ` niet.

Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 23:11
code:
1
2
3
4
5
6
root@pi:~ # cat foo
Hello World
root@pi:~ # cat bar
Hello World
root@pi:~ # diff foo bar &>/dev/null && echo "true" || echo "false"
true


code:
1
2
3
4
5
6
root@pi:~ # cat foo
Hello World
root@pi:~ # cat bar
Hello World1
root@pi:~ # diff foo bar &>/dev/null && echo "true" || echo "false"
false

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • Demo
  • Registratie: Juni 2000
  • Laatst online: 30-09 11:31

Demo

Probleemschietende Tovenaar

[b]deadinspace schreef op woensdag 03 juli 2013 @ 11:14:
Die backtick is echt de meest idiote syntax ooit; het is veel beter om $() te gebruiken, dat is veel leesbaarder en dan heb je die hele verwarring tussen ' en ` niet.
Heeft ook zeker mijn voorkeur, maar het ging mij er om dat yeadder in de goede richting zat maar het verkeerde leesteken gebruikte. Er staat mij ook iets van bij dat `` anders kan reageren dan $(), iets met verwerking van variabelen oid?

Unix doesn't prevent a user from doing stupid things, because that would necessarily prevent them from doing brilliant things.
while true ; do echo -n "bla" ; sleep 1 ; done


Acties:
  • 0 Henk 'm!

  • Slurpgeit
  • Registratie: November 2003
  • Laatst online: 18:00
Bash:
1
2
3
4
5
6
file1=$(cat $1)
file2=$(cat $2)
if ["$file1" == "$file2" ]
then
    echo "Files match."
fi


Zoiets? Command line wordt dan ./script.sh bestand1 bestand2. Al moet ik er wel bij zeggen dat dit echt super ranzig is, en dat 'diff' hier een stuk beter voor werkt :). Eventueel zou je 'cat' nog kunnen vervangen met 'md5sum'.

[ Voor 31% gewijzigd door Slurpgeit op 03-07-2013 11:29 ]


Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 23:11
Er is geen verschil. Backticks zijn ouder, minder flexibel (niet makkelijk te nestelen) en minder leesbaar:
http://pubs.opengroup.org..._chap02.html#tag_02_06_03

Het andere kleine verschil is dat tcsh alleen backticks ondersteund.
Slurpgeit schreef op woensdag 03 juli 2013 @ 11:26:
Bash:
1
2
3
4
5
6
file1=$(cat $1)
file2=$(cat $2)
if ["$file1" == "$file2" ]
then
    echo "Files match."
fi
Er moet altijd een spatie zitten tussen [ en je volgende logic. [ is in linux een apart programma genaamd "test". Doe je dit:
code:
1
["$file1"

Dan voeg je in essentie het programma uit genaamd (in het genoemde voorbeeld van TS):
code:
1
["Hello World"

Wat natuurlijk niet bestaat.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
root@pi:~ # man [
TEST(1)                          User Commands                         TEST(1)

NAME
       test - check file types and compare values

SYNOPSIS
       test EXPRESSION
       test

       [ EXPRESSION ]
       [ ]
       [ OPTION
Zoiets? Command line wordt dan ./script.sh bestand1 bestand2. Al moet ik er wel bij zeggen dat dit echt super ranzig is, en dat 'diff' hier een stuk beter voor werkt :). Eventueel zou je 'cat' nog kunnen vervangen met 'md5sum'.
In dit geval gebruik je gewoon diff voor het vergelijken van tekst bestanden en md5sum voor het vergelijken van binaire bestanden. md5sum is veel langzamer en diff heeft weinig zin op binaire bestanden.

[ Voor 70% gewijzigd door CurlyMo op 03-07-2013 11:36 ]

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • deadinspace
  • Registratie: Juni 2001
  • Laatst online: 20:04

deadinspace

The what goes where now?

Demoniac schreef op woensdag 03 juli 2013 @ 11:21:
Heeft ook zeker mijn voorkeur, maar het ging mij er om dat yeadder in de goede richting zat maar het verkeerde leesteken gebruikte.
Nouja, ik leer mensen dan liever de leesbare vorm aan :)
Er staat mij ook iets van bij dat `` anders kan reageren dan $(), iets met verwerking van variabelen oid?
Backslashes binnen `` worden geinterpreteerd, binnen $() niet (in ieder geval in bash en zsh, in dash weer niet lijkt het...):
% echo `echo \\`

% echo $(echo \\)
\

Ik vind het gedrag van $() zelfs logischer eigenlijk.
Slurpgeit schreef op woensdag 03 juli 2013 @ 11:26:
Bash:
1
2
3
4
5
6
file1=$(cat $1)
file2=$(cat $2)
if ["$file1" == "$file2" ]
then
    echo "Files match."
fi

... Al moet ik er wel bij zeggen dat dit echt super ranzig is, ...
Als het echt super ranzig is, waarom geef je die methode dan? :P

Ik wil daar eigenlijk toch nog even op inhaken, want die aanpak heeft toch wel wat haken en ogen... Zo geeft jouw script bijvoorbeeld "Files match." als je hem aanroept op twee bestanden met respectievelijk Hello world en Hello world (twee spaties) als inhoud. En wat als de opgegeven bestanden 5GB zijn? ;)
Wel dus, backslash interpretatie :)
[ is in linux een apart programma genaamd "test".
Jep. In veel shells is het overigens een builtin, voor de snelheid, maar dat doet verder niks aan je opmerking af :)
In dit geval gebruik je gewoon diff voor het vergelijken van tekst bestanden en md5sum voor het vergelijken van binaire bestanden. md5sum is veel langzamer en diff heeft weinig zin op binaire bestanden.
Hoezo heeft diff geen zin op binaire bestanden? Diff kan je van binaire ook gewoon vertellen of ze verschillen hoor. Diff heeft zelfs nog het voordeel dat hij bij binaire bestanden (en/of gebruik van -q) ophoudt met vergelijken zodra hij een verschil gevonden heeft, dus hij slechts een deel van de bestanden hoeft te vergelijken.

[ Voor 24% gewijzigd door deadinspace op 03-07-2013 11:49 ]


Acties:
  • 0 Henk 'm!

  • Slurpgeit
  • Registratie: November 2003
  • Laatst online: 18:00
deadinspace schreef op woensdag 03 juli 2013 @ 11:43:


Als het echt super ranzig is, waarom geef je die methode dan? :P
Omdat TS blijkbaar een script nodig heeft, anders zou diff prima werken :P
CurlyMo schreef op woensdag 03 juli 2013 @ 11:26:

Er moet altijd een spatie zitten tussen [ en je volgende logic. [ is in linux een apart programma genaamd "test".
Oeps, haast typo.

[ Voor 38% gewijzigd door Slurpgeit op 03-07-2013 12:53 ]


Acties:
  • 0 Henk 'm!

  • deadinspace
  • Registratie: Juni 2001
  • Laatst online: 20:04

deadinspace

The what goes where now?

Slurpgeit schreef op woensdag 03 juli 2013 @ 12:50:
Omdat TS blijkbaar een script nodig heeft, anders zou diff prima werken :P
Dan kan hij toch diff in zijn script gebruiken? :)

Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 23:11
Ik zie het probleem ook niet:

Bash:
1
2
3
4
5
6
7
#!/bin/bash

if diff foo bar &>/dev/null; then
        echo "true";
else
        echo "false";
fi


Of dit, als je dat makkelijker te lezen vind:

code:
1
2
3
4
5
6
7
#!/bin/bash

if [ $(diff foo bar &>/dev/null; echo $?) == 0 ]; then
        echo "true";
else
        echo "false";
fi

[ Voor 38% gewijzigd door CurlyMo op 03-07-2013 13:12 ]

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • amx
  • Registratie: December 2007
  • Laatst online: 22:42
deadinspace schreef op woensdag 03 juli 2013 @ 12:55:
[...]

Dan kan hij toch diff in zijn script gebruiken? :)
Ik wil in een if...then of een case statement ook een unieke invoer laten herkennen

Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 23:11
amx schreef op woensdag 03 juli 2013 @ 17:45:
[...]


Ik wil in een if...then of een case statement ook een unieke invoer laten herkennen
:?

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • amx
  • Registratie: December 2007
  • Laatst online: 22:42
...


nvm

Ik wilde een read input eerst naar een file wegschrijven, en dat is juist waarom de diff vergelijking voor mij omslachtiger in code is.
Waardoor STDOUT naar /dev/null een true/false oplevert zie ik overigens maar deels

[ Voor 70% gewijzigd door amx op 03-07-2013 18:15 ]


Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 23:11
Het checken op aanwezigheid van een specifieke string doe je met grep:
code:
1
2
3
4
5
if [ $(grep -c "Hello" foo) -ge 1 ]; then
        echo "true";
else
        echo "false";
fi
amx schreef op woensdag 03 juli 2013 @ 18:00:
Ik wilde een read input eerst naar een file wegschrijven, en dat is juist waarom de diff vergelijking voor mij omslachtiger in code is.
Waardoor STDOUT naar /dev/null een true/false oplevert zie ik overigens maar deels
Een STDOUT naar /dev/null onderdrukt welke uitvoer dan ook van het voorgaande commando. Het onderdrukt niet de return code. Het is de return code waar op gechecked word. Deze kan je in Bash opvragen via $?.

[ Voor 64% gewijzigd door CurlyMo op 03-07-2013 18:17 ]

Sinds de 2 dagen regel reageer ik hier niet meer

Pagina: 1