Reply for "AIX as it's best" - scripting..

Na.. Ha már LGee-nek szabad, én is előhozakodnék 2 faramuci szopatással amit az elmúlt 1-2 napban sikerül a kedves ksh, perl scripting nyelvek révén megélnem :)

#####################################
#1: perl-nek változó átadás shellből:

Az alap problémát a következő helyzetben nyomban láthatjuk:

# export NEWDATE="$SEC,$MIN,$HOUR,$DAY,$MONTH,$YEAR"
# echo $NEWDATE
00,00,00,1,0,2010
# perl -le 'use Time::Local;print timelocal($NEWDATE)'
Day '' out of range 1..31 at -e line 1

Mit is akartunk, és mi is történt? - Létrehoztunk egy NEWDATE változót, amit a már előre előkészített változók értékeivel feltöltöttünk. Biztos ami biztos ki is echo-ztam, hogy mindenki láthassa jó ez így. Majd mivel unix time-ot szerettem volna generálni, így gondoltam fogom magam, és átadom a perlnek az egészet, aztán örülök.. Mint láthatjuk a perl ezt nem így gondolta...
Azért biztos ami tuti alapon nézzük meg mi van ha nem egy változóba dobjuk ezt be:

# perl -le 'use Time::Local;print timelocal(00,00,00,1,0,2010)'"
1262304000

Jéé.. Így meg lefut..
Na akkor nézzük hol hibázik a koncepció: A perl is alapból a változó neveket $variant-ként kelezi ( $variant = változó, @array = tömb ) Tehát perl-en belül van lehetőségünk változókat hívni, ám mivel a ksh és a perl is ugyan olyan naming convention-t használ, így szopás van, mert a perl úgy gondolja, hogy azt a változót perl-en belül definiálták.. De mivel nincs definiálva, így csak szopás az eredmény...

Kis workaround-ként az alábbi randaságot találtam erre ki:

# echo "perl -le 'use Time::Local;print timelocal($NEWDATE)'"|sh
1262304000

Mit is csinálunk - hát fogjuk magunkat, felépítjük a teljes parancsot, mint egy string-et, aztán átadjuk az sh-nak ( ami amúgy egy ksh ), hogy futtassa már le. Tekintve, hogy a stringen belül a perl mint futtatóprogram definiálva van, így ez szépen át is megy a rostán..

#####################################
#2: ksh, meg a * karakter..

Alap szituáció amit szerettem volna: egy for ciklussal fussunk végig a /etc/security/passwd-n és nézzük meg kinek van "*"-ra beállítva a jelszava ( van ilyen ). Az elképzelés az alábbi volt ( a cilust most kihagyom, koncentráljunk most a lényegre :))

# if [ `grep -p ^username: /etc/security/passwd|grep password|awk '{print $3}'` != "*" ]
> then
> echo hi
> else
> echo ho
> fi
ksh: lost+found: 0403-012 A test command parameter is not valid.
ho

Na szóval: grepeljünk rá a username-re a /etc/security/passwd-n belül (-p :)), grepeljünk tovább a password sorra, majd awk-val kérnénk a 3. tömb tartalmát. Ha az eredmény nem "*" akkor hi, amúgy ho..
Mint látjuk ho-t kaptunk (ami szerint a 2 egyezik), de melette egy nagyon randaságot is:
ksh: lost+found: 0403-012 A test command parameter is not valid.

Megsúgom: Ez nem a passwd file-ban volt.. Aki szemfüles az már itt rájöhet amúgy hol szúrtam el :) .. Mindenesetre a ksh úgy érezte ezt jobb a tudtomra adni, de sajnálatomra ezzel nem lettem okosabb ekkor még..
Na akkor menjünk tovább:

# set -x
# grep -p ^username: /etc/security/passwd|grep password|awk '{print $3}'
+ grep -p ^username: /etc/security/passwd
+ awk {print $3}
+ grep password
*

Aham.. tehát az if-en belüli rész valóban hoz eredményt, méghozzá csillagot.. pont ezt szeretném összehasonlítani ugyebár.. És akkor jött az isteni fejbekólintás.. Mit is csinál ez a szerencsétlen??

# if [ * != '*' ]
> then
> echo hi
> else
> echo ho
> fi

Ha még nem tünt volna fel az egész: Amit én a grep-el kikérettem azt az if ágban a ksh szépen ki is értékelte, na nem mint stringet, hanem mint azt neki illik: Mindent behelyettesített amit talált.. Jelen esetben az épp aktuális mappa tartalmát, ahonnét ezt futtattam.. Ergo a megoldás: Rakjuk macskakörömbe az egész hóbelebancot..

# if [ "`grep -p ^username: /etc/security/passwd|grep password|awk '{print $3}'`" == '*' ]
> then
> echo hi
> else
> echo ho
> fi
+ grep -p ^username: /etc/security/passwd
+ awk {print $3}
+ grep password
+ [  == * ]
+ echo ho
hi

Öröm és bóduttá...

Hozzászólások

Node ez csak AIX-on fordul elő?
Mert szerintem ugyanez lenne a helyezet (vagy közel ugyanez) más UNIX-okon is, ksh alatt. Úgyhogy ez inkább ksh feature, mint AIX. Vagy akkor ennyi erővel a blogpost címében Solaris is lehetett volna például. Nem? (Vagy ott ksh93, itt meg ksh88 van?)
-------------------------------------------------------------------------------
Az életben csak egy dolog a szép, de az épp nem jut eszembe.

Slackware Linux 12.1 | 2.6.26.7-janos

Szóval nem mondtam, hogy ez AIX sajátosság lenne.. Nagy esélyel amit leírtál totál igaz a többi OS-re is valóban.. Ami miatt még is bele került a címbe az az volt, hogy pont ez alatt a rendszer alatt kódoltam, és épp Lgee egyik ilyen topicja volt megnyitva, úgy hogy gondoltam akkor már ilyen leszek..
De ha gondolod csak neked, és csak most egy tipikusan AIX-es szépség:

Alap szitu: cfgmgr nem mozdult, a jelek szerint a cfgefscsi miatt..

# kdb
The specified kernel file is a 64-bit kernel.
Preserving 1418178 bytes of symbol table
First symbol __mulh
START END <name>
0000000000001000 0000000003E5C050 start+000FD8
F00000002FF47600 F00000002FFDC940 __ublock+000000
000000002FF22FF4 000000002FF22FF8 environ+000000
000000002FF22FF8 000000002FF22FFC errno+000000
F100070F00000000 F100070F10000000 pvproc+000000
F100070F10000000 F100070F18000000 pvthread+000000
PFT:
PVT:
id....................0002
raddr.....0000000002000000 eaddr.....F200800110000000
size..............00080000 align.............00001000
valid..1 ros....0 fixlmb.1 seg....0 wimg...2
(0)> th -n cfgefscsi
SLOT NAME STATE TID PRI RQ CPUID CL WCHAN

pvthread+81D100 33233 cfgefscs SLEEP 1D113F 03C 27 0 F10001301814FDB0

(0)> cr 33233
ADDRESS SLOT ID FLAGS OWNER CHKSYNCH

0000000000033233 16888481418560072 A67D8081 B0EAE1FF B8EB01FF F0EBE1FFF84E8000

ID......... rcrid :A67D8081 vcrid :20EAC1FF
FLAGS...... flags :B0EAE1FF VALID PRIMARY RESTARTED BEING_CHKPTED BEING_RESTARTED
OWNER...... owner :B8EB01FF
VIRTUALS... lvpid :00000000D8EB81FF
........... lvtid :00000000E8EBC1FF
........... lvseq :20E8
CHECKPOINT. chksynch :F0EBE1FFF84E8000
........... chkfile :2A480006B57C781B

MEMBERS.... procpv :C0EB21FFC8EB41FF
SLOT PID #THS
C0EB21FFC8EB41FF -3383443229361455[kdb_read_mem] no real storage @ C0EB21FFC8EB41FF

____________________________________
Az embert 2 éven át arra tanítják hogyan álljon meg a 2 lábán, és hogyan beszéljen... Aztán azt mondják neki: -"Ülj le és kuss legyen!"..

#1: perl-nek változó átadás shellből

Ebbe én is belefutottam múlt héten. Én így kerültem meg a problémát:


typeset -x INDATE="2010-03-01" #vagy export

perl -e 'print $ENV{"INDATE"}'

--
A gyors gondolat többet ér, mint a gyors mozdulat.

1) mivel aposztrofok koze tetted a $NEWDATE -et, semmifele valtozot nem adtal at a perl-nek. Ha at akarnad adni, akkor biztositanod kell, hogy a shell kepes legyen kihelyettesiteni: ekkor idezojel kene az aposztrof helyett - erdekes modon igy mukodik is:


$ perl -le "use Time::Local;print timelocal( $NEWDATE )"                       
1262300400
$ 

b verziokent ha tenyleg at akarod adni, akkor ezt jelezd a perl-ben, peldaul a fentiekben emlitett modon, azaz nem


$NEWDATE 

, hanem


$ENV{NEWDATE} 

hasznalataval. Ekkor ugyanis a perl tud arrol, hogy neki egy kornyezeti valtozoval kene foglalkoznia. (Ami az elgondolkodtato, hogy ebben a helyes(nek latszo) formaban is megkapod a hulye hibauzenetet:


$ perl -le 'use Time::Local;print timelocal( $ENV{NEWDATE} )'
Day '' out of range 1..31 at -e line 1
$ 

Ehhez most faradt vagyok, hogy atlassam, hogy ez miert nem OK. Illetve ugy gondolom azert, mert a timelocal var 6 db parametert, ellenben kap egy db stringet.

2) Az, hogy Te nem tudod, hogy a shell milyen helyettesiteseket vegez (es miyen sorrendben), meg nem a shell hibaja. Altalaban elegge alap dolog, hogy ha valahol parancs vagy valtozohelyettesites tortenik, akkor mivel az eredmeny tartalmazhat szokozt, tabulatort es soremelest (alapertelmezett elvalasztokarakterek, $IFS), ezert ha *NEM AKARJUK* hogy a shell ezt utana tobb szonak ertelmezze, akkor idezojelbe kell tenni. Ezert van az, hogy normalisabb helyeken elegge felhivjak ra a figyelmet, hogy az esetek kb 99%-aban nem $v, hanem "$v" a javasolhato forma (esetleg bonyolithato : "${v}"), es ugyanigy a backtick is valoszinuleg idezojelen belul irando. (Ilyen jellegu problemat konnyebb elkerulni, ha az emberben tudatosul, hogy a [ ... ] az a test nevu parancs, aminek _parameterei_ alkotjak vizsgalando feltetelt - kovetkezeskeppen ugyanugy tortenik meg a shell helyettesites, mint ha [ helyett mondjuk echo lenne a parancs.

timelocal var 6 db parametert, ellenben kap egy db stringet

pontosan:


NEWDATE='00,00,00,1,0,2010'
export NEWDATE
perl -MTime::Local -E 'say timelocal( split q{,}, $ENV{NEWDATE} )'

De a valtozatossag kedveert ezek mind mukodnek (export nelkul is):


NEWDATE='00,00,00,1,0,2010'
echo "use Time::Local; print timelocal($NEWDATE)" | perl -l

NEWDATE='00,00,00,1,0,2010'
perl -le 'use Time::Local; print timelocal('"$NEWDATE"')'

NEWDATE='00,00,00,1,0,2010'
perl -MTime::Local -le 'print timelocal( split q{,}, $ARGV[0] )' "$NEWDATE"

NEWDATE='00,00,00,1,0,2010'
perl -MTime::Local -le 'print timelocal( eval $ARGV[0] )' "$NEWDATE"

Zahy masodik pontjanak lenyeget (tanulni, tanulni, tanulni) is csak tamogatni tudom, mert a fenti problemak egyike sem az AIX, ksh vagy a perl problemaja.

Illetve, ha jol sejtem, mi van az OP masodik problemaja mogott, akkor hadd hivjam fol a figyelmet, hogy a * az /etc/security/passwd-ben nem azt jelenti, hogy az adott user barmilyen jelszoval bejelentkezhet, hanem epp az ellenkezojet.

Zahy-nak a commentjére konkrétan nem tudtam mit írni, mert tényleg totál mindenben igaza volt.. Innen is látszik, hogy nem kóder vagyok, hanem csak rendszer admin..
Viszont a tanácsokat tényleg meg fogom fogadni, szóval tényleg köszönet érte.

Azt amúgy már fentebb leírtam miért is került bele az AIX a topic subject-be, de látom baki volt belevenni.. Most már mondjuk hagyom.

Amúgy a *-al kapcsolatban meg tudom, hogy azt jelenti.. Pont ezért akartam rákeresni ezekre..
____________________________________
Az embert 2 éven át arra tanítják hogyan álljon meg a 2 lábán, és hogyan beszéljen... Aztán azt mondják neki: -"Ülj le és kuss legyen!"..

Hajra, dicseretes a hozzaallas. De hogy irjak valami hasznosat is, javaslom kezdd az Advanced Bash Scripting Guide-dal! Ha kozben nap mint nap ksht hasznalsz, akkor neha ugyan idegesito lesz, hogy nem minden fog ugyanugy mukodni, mint a guide-ban, de 95%-a mukodni fog, es a lenyeg hogy ez szazszor jobban magyaraz, mint mondjuk a ksh man oldala.

Sztem ez már 1-2x szembe is jött :) Amúgy ksh-t napi szinten használok, meg elég gyakran írogatok ilyen kisebb scripteket is ( 1000 sor alatt ), szóval ilyen téren nincs problémám.. Amivel viszont van az az, hogy mivel autodidakta módon megy az egész, így amit csinálok az működik, de sokszor látom, hogy ronda..
Ez a bejegyzés is kb azért született, mert igyekeztem a munkámat megkönnyíteni egy script írásával (most tart 350 sornál, de még érzem, hogy a 10.-énél se vok) csak aztán szembejött, hogy van 1-2 dolog ami nem úgy megy, mint ahogy eddig megszoktam. Szó nem volt arról, hogy bármi is xar lenne, inkább annyi, hogy "aki ilyesmibe belefut az láthassa én mit találtam rá". Bocs ha félreérthető volt.

Viszont ha valaki nagyon akar akkor ahhoz hozzászólhat amit fentebb említettem cfgmgr-es problémával kapcs. :)) Az viccesebb, meg abban kicsit otthonosabban is mozgok :D
____________________________________
Az embert 2 éven át arra tanítják hogyan álljon meg a 2 lábán, és hogyan beszéljen... Aztán azt mondják neki: -"Ülj le és kuss legyen!"..

Haha.

De az a timelocal jo dolog.

PS. 'its' a helyes alak, az 'it's' azt jelenti: it is.

Ohh várj.. kb 10 percen át bújtam a manokat, csak hogy kiirassam a current unix time-ot.. Valami ilyenből indultam perl-en belül:

($second, $minute, $hour, $dayOfMonth, $month, $year, $dayOfWeek, $dayOfYear, $daylightSavings) = localtime();
$time = timelocal($second,$minute,$hour,$day,$month,$year);

Aztán a fejemhez csaptam, és lett belőle ez:
print time();

Hiába, látszik, hogy ezt még gyakorolni kell :)

____________________________________
Az embert 2 éven át arra tanítják hogyan álljon meg a 2 lábán, és hogyan beszéljen... Aztán azt mondják neki: -"Ülj le és kuss legyen!"..

Nálunk sajna még mindig van 4.3, 5.1, 5.2 is :) szóval ha scriptet írok arra már rég rájöttem, hogy törekednem kell arra, hogy mind1ik gépen menjen ( tudod mekkora hiány tud lenni 4.3 alatt az lsdev -p?? :( Helyette marad az odmget... )
____________________________________
Az embert 2 éven át arra tanítják hogyan álljon meg a 2 lábán, és hogyan beszéljen... Aztán azt mondják neki: -"Ülj le és kuss legyen!"..

a másodikhoz:

AIX 5L Korn and bash Shell Programming (Course Code AU23)
-> Unit 1. Basic Shell Concepts
--> Figure 1-16. Quoting Metacharacters

(s ráadásul nem először ... :'(

Ilyenre nem lehet mit mondani, nalam alap az, hogy minden parancskimenet, minden user altal piszkalhato valtozo behelyettesitese idezojelek kozott megy. Nem tudhatod, hogy mi jon vissza.

Amugy meg - szerintem ezt mar sokan mondtak - nagyon szeretheted a pipe jelet nyomkodni.


awk '/username:/ { if($0 ~ /password/) { if($3 == "*") { print $1 " hi" } else { print $1 " ho" } } }' /etc/security/passwd

Igy alaphangon. Persze, mivel nincs peldafajlom, igy nem tudom betesztelni, hogy nem vetettem-e hubat.
--


()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

Őőő.. Most nem teszteltem le, de ránézésére sztem ezzel pont hogy nem tudod helyettesíteni a grep -p-t ( feltételezed, hogy 1 sorban van a username, a password, és a *, holott nem )
Amúgy ebből a blogbejegyzésből sikerült 1-2 kellemetlen tanulságot levonnom:
- Hajnali 1 körül alkoholizálás után ne kezdjen az ember kódolni, mert az iszonyat primitív hülyeségeken is fennakad.
- Pláne ne kezdjen el róla blogbejegyzést írni ilyen állapotban, mert csak magát égeti le az ember..
- Scriptingből még mindig van hova fejlődnöm, de tekintve, hogy a munkám során ez nem nagyon elvárás, így talán még van remény...
- Legközelebb már tényleg csak technikai dolgokról írok.. Ezt a blogot pedig a saját szégyenfalamnak itt megtartom ( tekintve, hogy elég sok hasznos hozzászólás született )
____________________________________
Az embert 2 éven át arra tanítják hogyan álljon meg a 2 lábán, és hogyan beszéljen... Aztán azt mondják neki: -"Ülj le és kuss legyen!"..

En kerek elnezest. Elsiklottam a -p kapcsolo felett egyszeruen. Ilyenkor persze kisse bonyolultabb az ugy, ket agra kell bontani, es egy jelzovaltozoval figyelni.

A scriptingre raterve: noha nem elvaras, nagyon meg tudja az ember eletet konnyiteni az, ha fejleszti magat a scriptek irasaban. En eleinte roppant mod idegenkedtem az Awk-tol, mert nehez, bonyolult, regex alapu nyelvnek tartottam. A jellemzesben nem sokat tevedtem, viszont kozben a legjobb baratok lettunk, espediglen azert, mert hihetetlen nagy segitseg tud lenni az, ha egy szovegfajlbol ki tudok dolgokat szedni par pillanat alatt anelkul, hogy sokat kene kuszkodni.
--


()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.