shell cgi script - nem értem

Van egy jó kis RPI, rajta egy kamera, web szervernek fut a busybox.
Itt a kép készítő/megjelenítő része:


WEB_IMAGE="../data/img-$$.jpg"
raspistill -vf -hf -n -w 640 -h 480 -t 200 -o $WEB_IMAGE
echo "[img style=\"width: 640px; height: 480px;\" alt=\"$WEB_IMAGE\" src=\"$WEB_IMAGE\"]"

(A relációs jeleket szögletesre cseréltem)
Érdekes módon, a data könyvtárban egy (egyébként teljesen jó) img-3223.jpg jön létre viszont, a WEB -re img-3227.jpg megy ki, a busybox pedig 404 hibát ír. Mintha a raspistill parancs "önállósítaná" magát és felülírná a kép nevét.
Működött nekem egy ilyesféle script, de ott a egy másik "folyamat" hozta létre a képet, addig lock filet használtam amíg el nem készült, majd akkor "gyorsan" lemásoltam a WEB számára.
Viszont akkor sem értem miért változik a $WEB_IMAGE változóm. Ötlet?

Hozzászólások

Mivel CGI ként fut, így minden hívásnál más lesz a process id, ami a $$ változó ad vissza.

Fedora 20, Thinkpad x220

Ezért is tettem bele a $$ változót - így mindenki aki ránéz, az kap egy saját lenyomatot.
De egy-egy meghíváson belül nem változhatna ... hacsak újra nem hajtja végre az értékadást, mintha azt írtam volna

raspistill -vf -hf -n -w 640 -h 480 -t 200 -o "../data/img-$$.jpg"

Így a shell egy másik értéket pakolna oda.

* Én egy indián vagyok. Minden indián hazudik.

Mondjuk eleve nem tűnik jó ötletnek, mert a keletkező kép ottmarad és nem takarítja el senki, de ez csak mellékes.

Viszont... így végiggondolva, hogy mi történik: a CGI könyvtárból futtatod a shell scriptet, de a kép útvonala is relatívként van megadva, ami sanszos, hogy webről nem elérhető ebben a formában:
http://szervered/cgi-bin/script.sh a szkripted, http://szervered/../data/img-3434534.jpg lenne a képhez tartozó URL.
Tartok tőle, hogy ez egy érvénytelen cím lesz. (upd: feltéve, hogy a cgi-bin, ahonnan a szkripted fut, nem közvetlenül a documentroot alatt van - én azt szoktam meg, hogy a cgi-bin könyvtára valahol a /usr/lib, /var/lib vagy valami ezekhez hasonló helyen van, a documentroot meg pl. a /var/www. Ilyen esetben biztosan nem működik)

A WEB_IMAGE-be én csak a fájl nevét tenném, a többit más változóba pakolnám, mert az URL és a fizikai elérési út többnyire eltérnek egymástól.

upd2: ami még eszembe jutott, hogy ez a képkészítő szoftver nem teszi-e magát háttérbe miután elindult?

Igen. Sok hasonlót olvastam, de ha kicserélem egy fixre pl. "../data/img.jpg" akkor tökéletesen működik (egy felhasználóval).
A busybox httpd nem igazán ilyen szofisztikált cucc. Meghívása így fest:

$busybox -fvvv -p 40080 -h /home/tovis/public_html

De a "gyökér" lehetne akár a /tmp/vlmi is, a lényeg hogy legyen jogosultsága olvasni és futtazni annak aki a fenti parancsot begépelte az adott könyvtárban.
Amit te említesz a szokványos apache és hasonló kaliberű http szervereknél igaz. Külön felhasználó és root jogosultságokkal létrehozott könyvtárak.

* Én egy indián vagyok. Minden indián hazudik.

Parancssorból futtatva is ugyanaz a jelenség?

Elso koron $WEB_INMAGE valtozoban egyel tobb N betu van mint kellene ;)

Masodik korben: milyen shellt hasznalsz? Probaltad bash-sel is?

asd

ha valóban egyedi azonosítót szeretnél a képnek, akkor inkább használj pl.
`date | sha256sum`
vagy hasonlót fájlnévnek.

Ha egy scriptet akarnék debuggolni, ilyesmit próbálnék:


#!/bin/sh

exec 2>/tmp/debug.$$
set -xv

...

Na most teljesedett ki a káosz a fejemben :(
Megírtam a kis screen alapú scriptemet, és a hiba eltűnt ...
Majd megint megpróbálom a busybox scripten kívüli meghívását ...
Ez egyre érthetetlenebb.

* Én egy indián vagyok. Minden indián hazudik.

Azt en se, de lehet, hogy maskepp megoldva egyszerubben mukodik.


#!/bin/sh
# image.cgi

WEB_IMAGE="../data/img-$$.jpg"
raspistill -vf -hf -n -w 640 -h 480 -t 200 -o "${WEB_IMAGE}"
echo "Content-Type: image/jpeg"
echo "Content-Disposition: attachment; filename=\"${WEB_IMAGE}\""
echo
dd if="${WEB_IMAGE}"

<!-- display.html -->
<img src="/image.cgi" style="width: 640px; height: 480px;" />

Az img tag ignoralja a content-disposition headert, igy a kep mindenkeppen embedded modon jelenik meg, viszont ha valaki a cgi-ben direktben hiv ra, akkor letolti az adott kepet.

Tipp: a PID-et felhasznalni rettenetesen rossz otlet, semmi nem garantalja, hogy egyedi legyen. En inkabb egy unix timestamppel probalkoznek.
--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. 

Sőt, ha rendes akarsz lenni, küldhetsz egy Content-Length-et is (nem kötelező, de lehet, hogy egyes komponensek hasznát veszik).


echo "Content-Type: image/jpeg"
echo "Content-Disposition: attachment; filename=\"${WEB_IMAGE}\""
ls -l "${WEB_IMAGE}" | (read A A A A SIZE A; printf "Content-Length: %d\n" "$SIZE")
echo
cat "${WEB_IMAGE}"

Lehet, hogy valamit nem jol ertek, de szerintem ez egy CGI szkript, ami akkor fut, amikor meghivjak (a juzer bongeszobol meg akarja nezni a kamera pillanatnyi kepet). Ilyenkor a szkript lekeri a kameratol a pillanatkepet egy egyedi nevu file-ba, eleberak egy fejlecet, es az egeszet a juzer arcaba tolja. Hol van itt szukseg a letrehozasi idore?

Ö... a pid miért nem lesz garantáltan egyedi, míg fut a processz???
(annak meg szerintem elhanyagolhatóan kicsi az esélye, hogy a processz vége és a kép kiküldése közt ismétlődjön. Különösen azért, mert a legtöbb linuxos szerver a mai napig növekvő sorrendben osztja a pideket)

OFF: Alapvetően "elkeseredésemben" a jelenség érthetetlensége miatt dobtam fel ezt a topicot. A jelenséget még mindig homály fedi, viszont kaptam több nagyon érdekes tippet, amit köszönök! Érdemes volt feldobni.
Alapvetően ez még csak egy próba próbája. Az nagyon érdekesen hangzik, hogy pl. dd -vel "pakoljak ki" képet - meg sem fordult a fejemben.

Az igazság az, hogyha jobban belemélyedünk én egy kis megfigyelő kamerát akarok összerakni, számos extra szolgáltatással. Az ilyen kamerák 24 órában működnek, érzékelnem kellene a látótérben jelentkező mozgást, ami feltételez egy referencia képet, beleszámítva a nappali/éjjeli megvilágítást ("noir" kamera - nincs benne az infra szűrő). Kellhet egy fajta követés, azaz valamilyen periodicitással készíteni kell képeket és letárolni a háttérben és persze kell a "pillanatnyi" kép. Az rpi kamera szépsége, hogy rengeteg beállítási lehetősége van, míg egy a kereskedelemben kapható kamera ezeket erősen bekorlátozza és nagyságrendekkel drágább.
Így ez a kis "kattintsunk egyet" csak egy próbácska.

* Én egy indián vagyok. Minden indián hazudik.

Nem próbáltam. Először is nem értem - exec 2>/tmp/vlmi - mit hajt ez végre?
bash -x script.sh

illetve mintha #!/bin/sh -x is ugyanezt eredményezné.
a set -vx az még érthető - verbouse és trace.
És amint mondtam a mostani felállásban a hiba eltűnt.

* Én egy indián vagyok. Minden indián hazudik.

> Nem próbáltam.

Akkor valószínűleg nem is segített a hibakeresésben.

> Először is nem értem - exec 2>/tmp/vlmi - mit hajt ez végre?

Ha nem is akartad megnézni a leírást, mondjuk megkérdezhetted volna itt... azt jelenti, hogy a script error-kimenete ettől kezdve a /tmp/vlmi legyen (vagyis maradjon meg, hogy meg lehessen nézni.)

Várj csak, ez azt jelenti, hogy a scripten belül átirányítom az stderr -t?
Szokatlan nekem, általában a script futtatásakor szoktam ilyet megadni, de cgi esetén ez tényleg jobb!
Igyekszem nem elfelejteni, legközelebb (biztos lesz ilyen) kihasználom :)

* Én egy indián vagyok. Minden indián hazudik.