Bash

Fórumok

Sziaszok!

Egy kérdésem lenne:

Hogy tudnám megoldani azt, hogy egy parancsot lefuttatva (bármilyen parancsot) azt akarom vizsgálni, hogy mit ad vissza, tehát pl.: ls parancs esetén milyen könyvtárakat és fájlokat ad vissza, azt nem tudom , hogy mi van benne, tehát | grep "valmi" nem jó, tehát összefoglalva: csak annyit szeretnék vizsgálni, hogy add e vissza valamit vagy sem, ha visszaad akkor ok, ha nem ad vissza semmit akkor nem ok. (egy if-be szeretném tenni)

Remélem érthető volt,

köszönöm

Hozzászólások

sajna google nekem nem adott választ a kérdésemre, de a te linked sem, még1x, nem fájlokat és könyvtárakat akarok vizsgálni, hanem egy parancs kimenetét szeretném vizsgálni, az ls elég hüle példa volt:(

Kiadok egy parancsot és annak a kimenetét szeretném vizsgálni, van kimenet vagy nincs, sajnos nem tudom mi lesz a kimenet ezért vagyok meglőve:(

> összefoglalva: csak annyit szeretnék vizsgálni, hogy add e vissza valamit vagy sem,
$? kell vizsgalnod

ls /fasdfasdfsad
echo $?
ls /tmp
echo $?

de persze van mas megoldas is
ls | wc -l

Ha a visszatérési értékre gondolsz (0,1,stb...) akkor ha jól emlékszem a $? -el tudod megvizsgálni.
A visszatérési értékeket pedig elvileg a parancs man-jában megtalálod.

Csak egy példa:
Tételezzük fel, hogy az ls 1-et ad vissza hibakódként, ha nem létezik a könyvtár és 0-t ha létezik.
ls /mnt/eznemletezik
echo $?
1

ls /mnt/ezletezik
echo $?
0

Egyébként meg pipe és hasonlók.
Az ls-es példánál maradva:
a=`ls -all /mnt/valami | grep -i akarmi.txt | cut -f3 -d' '`
#Megkeresed az akarmi.txt az ls 3. oszlopban adott tulajdonságát...
echo $a
#és máris használhatod :)

szerk: megelöztek :)

Egyébként pedig nagyon-nagyon nézz körül, ha egyszer mégis arra vetemednél, hogy azt vizsgáld hibadetektálásra, hogy van-e kimenet, vagy nincs, ui. egyik programnál az a jó lefutás ismérve, hogy van kimenet, másiknál az, hogy nincs, és akár mindkettőnél tűnhet úgy, hogy minden rendben, viszont a hibacsatorna (stderr - sürgősen utánanézni, ha még nem ismerős) jelezhet számodra problémás csillagegyüttállást.

Van benne rendszer, de téves hozzáállás az egyes parancsok dokumentációja legalább a bevezetője elolvasűsa nélkül bármelyik viselkedést feltételezni.

Nem, nem voltál érthető. Státuszkódot minden parancs ad vissza, normális esetben 0-t akkor, ha sikeresen futott le. Kérdés, neked mi a sikeres.
$ mkdir yyy
$ cd yyy
$ ls
$ echo $?
0
$ touch lo
$ ls
lo
$ echo $?
0
$

Természetesen az is vizsgálható, hogy amit kiír a program, az a nagy büdös semmi, vagy van esetleg benne valami.

$ rm lo
$ ls
$ [ -z "`ls`" ] && echo ures
ures
$ touch lo
$ [ -n "`ls`" ] && echo nem ures
nem ures
$

Ahogy még szokták (a $? helyett):

parancs && echo "Hakuna matata" || echo "Ajajaajj :("

Ez már ízlés szerint fűszerezhető tovább.

Zahy megoldása "szebben":

if [-z "$(parancs)" ]
then
echo Jajaj
fi

Ez konkrétan akkor sír, ha a parancs nem ír ki semmit.

"igen, van ezzel még proléma bőven."

Nem annyira :D

if [-z "$(parancs)" ]

:D

fisher@zsebi:/tmp/alma$ touch 'a -o -n a'
fisher@zsebi:/tmp/alma$ if [ -z $(ls) ] ; then echo ures; fi 
ures
fisher@zsebi:/tmp/alma$ if [ -z "$(ls)" ] ; then echo ures; fi 
fisher@zsebi:/tmp/alma$ rm a\ -o\ -n\ a 
fisher@zsebi:/tmp/alma$ if [ -z "$(ls)" ] ; then echo ures; fi 
ures

Amit Zahy írt, abban is ott voltak a megfelelő idézőjelek, csak szerintem jobban olvasható a $(parancs) a `parancs` helyett (meg mintha már ez is lenne a javasolt vagy mi).

Az a jó ebben a POSIX-ban, hogy a szabvány megalkotásakor már létező konstrukciókat eldobnak. Pl:
$( < file ) ez ksh-ban ezer éve ismert (és a $(cat file) megfelelője, csak éppen spórolunk egy fork+exec párost), ellenben az opengroups-os specifikáció az ilyet kifejezetten mint "unspecified result" jellemzi.

Mondjuk ez már színtiszta filozófiai kérdés (avagy feladat- és/vagy helyfüggő), hogy a(z első szinten) csak rejtett fájlokat/könyvtárakat tartalmazó könyvtár az üres-e. Remek vitákat lehetne erre építeni és/vagy bugokat rejteni így scriptekbe :) Lásd: http://hup.hu/node/114931?comments_per_page=9999#comment-1463707 :D

Te egerész!

van itt egy-két directory, ahol a

[ -z $(ls) ]

értelmes időben nem fut le, viszont a

[ 0 -eq $(ls | head| wc -c) ]

az lefut.

Ezt gondold át egy kicsit. Mivel az ls *rendez*, ezért össze kell szednie az összes fájlnevet. Következésképpen maga az ls ugyanannyi ideig fog futni. (Plusz head és wc.) Persze ha beleteszed a más által már javasolt -f opciót, akkor már nyerhetünk vele, bár én azzal együtt se strapálnám magam a számolgaással (csak hogy spóroljak egy processzt), hanem mondjuk így:

[ -z "`ls -f | head`" ]

(Nyilván backtick vagy dollár-zárójel, az kb mindegy. lx-nek meg azt üzenem, backtick is egymásbaágyazható, csak ember legyen a talpán, aki mondjuk egy 3x egymásbaágyazott esetben átlátja:

parancs4 `parancs3 \`parancs2 \\\`parancs1\\\`\``

vs

parancs4 $(parancs3 $(parancs2 $(parancs1)))

Hogy tetszik? A sorszámok természetesen a végrehajtás sorrendjére utalnak.)

Szerk: most tudatosult bennem, hogy a rejtett fájlokra én se figyeltem. Finomítanék:

[ -n "`ls -fA | head -1`" ]

Ahol -A opció nincs, ott -a, és nem -1 hanem -3 :-)

Szóval legyen az ls-nek A opciója.

igen, emiatt bukta a -f. Jónak tünik a `ls -AU --color=never`
Bár, ahogy a világ fejlődik, simán kellhet a locale-mentes verzió:
`LC_ALL=POSIX ls -AU --color=never`

Más.

Egyébként én arra a nem teljesen nyilvánvaló dologra figyelmeztettem, hogy a `ls` esetén a teljes struktúra string reprezentálása kifejtődik a parancssorba, és igy esetleg extrém méretű parancssor keletkezik, míg a `ls | head` esetén ennek mérete limitált. Valóban, az `ls|head` az kétanyi processz, mint az `ls`, ennek is lehet szerepe egy masszív ciklus belsejében.

A lezáró '| wc -c' az csak egy már-már paranoid ovatosság. Nem vagyok abban biztos, hogy a test parancs tényleg körültekintően kezeli a paramétereit. Nem szokták a setuid parancsokhoz hasonlóan vizsgálni, egy kis BOF észrevétlenül befigyelhet, és kész a baj. Jobban hiszek a stdin/stdout értelmes kezelésében, azt könyebb jól megvalósítani, mint a paraméter kezelést.

Még jó, hogy a linux-kezdőben folyatunk eszmecserét, ha ezt szegény heroes83 mind végigolvassa, nem mer majd egy sort sem leírni :-)

Óvatosan azzal az && || kombóval. Ha az korrekten úgy működne, ahogy szeretnéd, akkor az && illetve a || mögött nem csak egyetlen parancs állhatna, hanem akár több is, kapcsos (vagy kerek) zárójelek között. De már a lenti harmadik parancs jelzi, hogy valami ott nem kerek. (Pontosabban a fent jelzett módon nem igazán javasolt vele kiváltani az if-then-else-fi összetett parancsot.

1 $ true && echo true || echo false
true
2 $ false && echo true || echo false
false
3 $ true && false || echo false
false # hoppácska!
4 $ true && { echo true ; false ;} || echo false
true
false
5 $

Bizony. Ezzel nagyon vigyázni kell!
Ha amolyan if-then-else módon akarod megoldani és mindenféleképpen, egy ilyet javaslok (már főleg nem neked, hanem úgy mindenkinek):

parancs && ( parancs_then ; true ) || parancs_else

Így kiküszöbölheted azt, ha a parancs_then lefutása hibás, akkor a parancs_else ne hajtódjon végre (meg a macska ne mászódjon fel a fára).