script meghívás

Érdekes dologra keresnék választ, megoldást. A feladat a következő. Van 3 futtatható szkript fájlom. A,B,C
Jelenleg  a C fájlt megtudom hívni a B fájlból, és ez a C el is végzi a dolgát. Ez a C többször is lefuthat, s ennek megfelelően adatokat exportál ki. 

Viszont most felmerült az, hogy az A fájlból is szeretném meghívni, de az adatok exportálása maradjon ki, mivel csak a legelső futásakor feldolgozott adatokra van szükségem. 
Gondoltam hogy ebbe az ominózus C fájlba berakok egy feltételt, hogy azt nézze ki hívta meg, s annak megfelelően exportáljon vagy ne. De nem tudom megoldható-e ez. S igen - mindezt bash shellben.

Hozzászólások

ps -hp "$PPID" -o comm

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

> Gondoltam hogy ebbe az ominózus C fájlba berakok egy feltételt, hogy azt nézze ki hívta meg

Ó, ne már! Adj neki egy paramétert inkább, amit az A-ban megadsz, a B meg továbbadja ha volt ilyen paraméter.

Így van, ez a legelegánsabb megoldás. Webscripenél is eleinte így adták meg a paramétereket GET-tel, ezt igaz később biztonsági alapon mellőzték. Ebben az a jó, hogy nem egészen POSIX kompatiblis shellekben is tuti működni fog, mert az $1-et minden unixlike OS shellje ismeri, és azonosan kezeli, a $$, $!, $PPID-t nem biztosan. Pont a legelterjedtebb, POSIX kompatiblis shellek pont lekezelik, pl. bash, zsh, dash, ksh, de arra is kell számítani, hogy valaki perverz csh-val, fish-sel, nushell-lel meg egyebekkel megy neki a feladatnak. Már pedig #!/bin/sh-nál nem tudni pontosan milyen shell fog futni, mire van linkelve. Azért ne feledjük, hogy nem csak Linuxból áll a világ. Ezt némileg ki lehet váltani #!/bin/bash vagy #!/usr/bin/env bash segítségével, de ezzel lehet szükségtelen függőséget is beemelünk a célrendszeren a script mellé.

Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”

a.sh
#!/bin/sh

./c.sh A

b.sh
#!/bin/sh

./c.sh B

c.sh
#!/bin/bash

parent=$1

echo $parent


Én úgy értelmeztem, hogy az A-nak is a B-t kell hívnia. Így:

joco@joco2:/tmp$ cat > a.sh
#!/bin/bash
./b.sh a
joco@joco2:/tmp$ cat > b.sh
#!/bin/bash
./c.sh ${1:-b}
joco@joco2:/tmp$ cat > c.sh
#!/bin/bash
echo $1
joco@joco2:/tmp$ chmod u+x a.sh b.sh c.sh 
joco@joco2:/tmp$ ./a.sh 
a
joco@joco2:/tmp$ ./b.sh 
b
joco@joco2:/tmp$ 

Szia!
Ha jól értem, akkor mondjuk van 1db változód ennek a változónak az értékét akarod elérni a másik szkripten belűl.

Megoldható csak kell egy "export" funkció:

a.sh
VAR1="valami"
gdb --batch-silent -ex "attach $PID" -ex 'set bind_variable("VAR1","${VAR1}",0)'

b.sh
./a.sh
VAR2=$VAR1
gdb --batch-silent -ex "attach $PID" -ex 'set bind_variable("VAR2","${VAR2}",0)'

c.sh
./b.sh
VAR3=$VAR2

 

Nem jó irány - két script több,mint egy, több a karbantartási igénye, aztán ha kiderül, hogy valamelyik funkció mégis kell mindkét esetben, akkor vagy duplán kell megvalósítani, vagy egy n+1 scriptbe kiszervezve a c1 és c2-ből is hívogatni...
A korábban javasolt paraméterezze a C jelű scriptet, és az átadott paraméter alapján döntsön a scriptben adott részek kihagyásáról.

A két kissebb script karbantartási költsége elvileg nagyobb mint egy scripté de nem kétszer akkora. Lehet a különböző branchek tisztán tartása több munka mint két külön script karbantartása.

Gyakorlatilag a paramáter hatására a script egy része nem fut, tehát fölösleges. Valamint ezzel egy booleant ad át ami minden clean code elmélet szerint rossz és kerülendő.

" aztán ha kiderül" ez tesz mindent túlbonyolulttá. Egy gyenge "talán" miatt úgy csinálni hogy majd egyszer ha netalántán kell akkor könyebb legyen használni, és valószínűleg nem is lesz, mert nem valószínű hogy módosítás nélkül lehet majd használni. Amikor felmerül az igény akkor majd újra refaktorálás jön, ha felmerül.

// Hocus Pocus, grab the focus
winSetFocus(...)

http://c2.com/cgi/wiki?FunnyThingsSeenInSourceCodeAndDocumentation

"Gyakorlatilag a paramáter hatására a script egy része nem fut, tehát fölösleges. Valamint ezzel egy booleant ad át ami minden clean code elmélet szerint rossz és kerülendő." Azaz valamennyi parancssori, paraméter nélküli kapcsoló rossz és kerülendő (hiszen mindegyikkel csak egy boolean kerül átadásra a programnak) , helyettük a kapcsolók minden valid mintázatára külön program készüljön?
 

Máshogy kelett volna fogalmaznom, nyílván nem kell kapcsolóként egy különálló program.

Viszont ebben az esetben két jól elkülöníthető szerepkör van, funkció mentén már lehet vágni.

// Hocus Pocus, grab the focus
winSetFocus(...)

http://c2.com/cgi/wiki?FunnyThingsSeenInSourceCodeAndDocumentation

Azaz valamennyi parancssori, paraméter nélküli kapcsoló rossz és kerülendő (hiszen mindegyikkel csak egy boolean kerül átadásra a programnak) , helyettük a kapcsolók minden valid mintázatára külön program készüljön?

Ez így leírva valóban faszságnak tűnik elsőre, de azért gyártottam én már 8-10 darabos wrappert script gyűjteményt olyan cmdline app elé, ami harmincvalahány _kötelező_ paramétert várt. Soha ne mondd, hogy soha. :P

Végül is úgy oldottam meg, hogy a C szkriptet --e vagy --q paraméterrel hívom meg. --e(exportál, --q=lekérdez.

A C szkripteben meg egy feltétel vizsgálja hogy a a $1 micsoda.

if [ "$1" = "--e" ]; then
    export="yes"
fi

exporTdata () {
    if [ "${export}" = "yes" ]; then
        export blabla    
    else echo "csak az eredmény"
    fi
}

Nem tudom talán kihagyhatnám az első feltételt, de így átláthatóbb.

Ez így van, de nem kötelező, csak puszta konvenció. Lehet akármilyen, akárhány karakteres paramétert egy, kettő, három, több vagy akár nulla kötőjellel, perjellel is megadni, ízlés és perverzió kérdése, hogy mire készítik fel a binárist vagy scriptet, pl. DOS-os meg Windows-ról jött Matyikból simán kinézem, hogy perjelet erőltetnek. De a legsztenderdebb valóban az, amit írsz, erre áll rá a legtöbb ember keze, rutinja, mindenki erre van rászocializálva. Valemenyire ez a sztenderd megoldás az elgépeléstől is véd, nehogy az legyen, hogy valaki egy kötőjel után egy hosszú paramétert akart begépelni, de rárángott a keze túl korán az Enter-re, erre csak egy karakteres paraméterrel futtatja a parancsot, és ez véletlen másik rövid (egy karakteres) paramétert eredményez, aminek más a hatása. Például script -remove, de csak script -r után véletlen futtatásra kerül, és nem minden szoftvernél van az, hogy a két paraméter ugyanaz (bár ez is ajánlott, hogy a hosszú paraméter első karaktere legyen a rövid paraméter), azaz nem garantált, pl. a példánál maradva --remove kapcsoló nem biztosan lesz azonos a -r kapcsolóval, ami pl. állhat recursive jelentésben is.

Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”

Sőt a POSIX szerint ez is összetettebb. Lássuk az alábbi két példát:

while ((opt = getopt(argc, argv, "get")) != -1) {
    switch (opt) {
        case 'g':

while ((opt = getopt(argc, argv, "g:et")) != -1) {
    switch (opt) {
        case 'g':

Az első tényleg -g -e -t kiértékelésű, a másodikban viszont egy "optarg" nevű globális változőban jelenik meg a -g utáni argumentum.