Nowe posty

Autor Wątek: [BASH] niegrzeczne find  (Przeczytany 6696 razy)

602tryliardy

  • Gość
[BASH] niegrzeczne find
« dnia: 2008-12-13, 21:01:52 »
Nie wiem, gdzie to wrzucić, tutaj chyba najlepiej pasuje.

Otóż find zachowuje się w sposób niezmiernie niezgodny z oczekiwaniami. Podczas wpisywania zapytania z operatorem logicznym or... nie działa -printf.

Dziwne nie?

Konkretniej: mam w katalogu dwa pliki, a i b, obydwa niepuste

 find  -user piotrek  -o  ! -empty -type f
daje rezultat:
.
./b
./a

jak dam z printf
find  -user piotrek  -o  ! -empty -type f -print
to nic nie wypisuje!!

natomiast, jak zamiast -o dam -a (no przecież w tym wypadku oba wyrażenia są prawdziwe, z and'em i z or'em) find  -user piotrek  -a  ! -empty -type f -print
to wypisuje to, co ma wypisywać:
./b
./a



Czy ktoś jest w stanie wytłumaczyć, dlaczego tak się dzieje? Czy może to jest bug?

//EDIT
Acha i jeszcze jedno:
nie tylko print się tak zachowuje, printf i exec to samo!

arctgx

  • Gość
[BASH] niegrzeczne find
« Odpowiedź #1 dnia: 2008-12-13, 21:23:31 »
Nie próbowałem nigdy, ale jak to bywa z printf, prawdopodobnie musisz podać co ma find pokazać i w jakiej kolejności, np. find -printf 'nazwa to %f\\n' (dałeś mi pretekst do wypróbowania).

Szczegóły w manualu (po polsku jest).

Find okazuje się bardzo grzecznie wypisywać Ci pusty zbiór pól funkcji printf :)

602tryliardy

  • Gość
[BASH] niegrzeczne find
« Odpowiedź #2 dnia: 2008-12-16, 22:09:07 »
No właśnie to nie jest tak...

printF owszem bierze argumenty, ale ja używałem print a (bez f).

Jeszcze jeden przykład:

find -user piotrek -a -not -empty -print
find -user piotrek -o -not -empty

dają rezultat:

./a
./b

find -user piotrek -o -not -empty -print

nie wypisuje nic!

arctgx

  • Gość
[BASH] niegrzeczne find
« Odpowiedź #3 dnia: 2008-12-17, 01:08:02 »
Cytat: 602tryliardy
Podczas wpisywania zapytania z operatorem logicznym or... nie działa -printf.

jak dam z printf
find  -user piotrek  -o  ! -empty -type f -print
to nic nie wypisuje!!
Skąd mam wiedzieć, gdzie robisz literówki?

Sam zacząłem zastanawiać się dlaczego tak jest i spojrzałem do polskiego podręcznika. Jest on już nieaktualny, ale znalazłem co trzeba, jak się zdaje:

Cytat: man find
Wyrażenie  jest  złożone  z  opcji  (które  tyczą  się  raczej ogólnego działania, niż przetwarzania konkretnego pliku i zawsze zwracają prawdę), testów (które sprawdzają wartość prawdy lub  fałszu)  i akcji  (które  mają efekty uboczne i zwracają wartość prawdziwą lub fałszywą); wszystkie te elementy są rozdzielone operatorami.  -and jest domyślnym operatorem, przyjmowanym w przypadku pominięcia go w jawnym zapisie. Jeśli wyrażenie nie zawiera innych akcji niż -prune, to na wszystkich plikach, dla których jest ono prawdziwe, wykonywany jest -print.
(...)
-print Prawdziwe; wypisuje pełną nazwę pliku na standardowe wyjście. Za nazwą daje nową linię.
(...)
 OPERATORY
     Wymienione w malejącym priorytecie:

     ( wyraż )
            Wymusza pierwszeństwo.

     ! wyraż
            Prawdziwe jeśli wyraż jest fałszywe

     -not wyraż
            To samo co ! wyraż.

     wyraż1 wyraż2
            And (jawny); wyraż2 nie jest analizowany jesli wyraż1 jest fałszywe.

     wyraż1 -a wyraż2
            To samo, co wyraż1 wyraż2.

     wyraż1 -and wyraż2
            To samo, co wyraż1 wyraż2.

     wyraż1 -o wyraż2
            Or; wyraż2 nie jest analizowane jeśli wyraż1 jest prawdziwe.

     wyraż1 -or wyraż2
            To samo, co wyraż1 -o wyraż2.

     wyraż1 , wyraż2
            Lista; zarówno wyraż1 jak i wyraż2 zawsze są analizowane.   Wartość  wyraż1  jest  niszczona;
            wartość listy jest wartością wyraż2.
Akcja to też wyrażenie. Zgodnie z kolejnością wykonywania operatorów, najpierw użyte jest -not dla -empty, potem powstały twór (po naszemu 'plik jest niepusty') łączony jest niewidzialną koniunkcją z prawdziwym zawsze wyrażeniem -print, co daje w efekcie prawdę. Finda jednak ten z kolei twór nie obchodzi, bo jest on drugim składnikiem alternatywy z wyrażeniem '-user piotrek'. Prawdziwość tego wyrażenia pociąga ignorowanie reszty.

Dodałem nawiasy nic nie wnoszące dla interpretacji, ale obrazujące tę kolejność.
 find \\( -user piotrek -o \\( \\( -not -empty \\) -print \\) \\)
Wystarczy podmienić użytkownika na innego istniejącego, by zainteresować finda drugim składnikiem alternatywy.

Find jest grzeczny :P

602tryliardy

  • Gość
[BASH] niegrzeczne find
« Odpowiedź #4 dnia: 2008-12-26, 18:40:41 »
Takie zawiłości...

Dzięki wielkie za pomoc :-))

arctgx

  • Gość
[BASH] niegrzeczne find
« Odpowiedź #5 dnia: 2008-12-27, 03:22:13 »
Bez przesady, to kilka klocków elementarnej logiki tylko :P