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?
- 8117 megtekintés
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
- A hozzászóláshoz be kell jelentkezni
A raspistill egy pillanatképet készítő program, ha minden igaz.
Minden futásra új néven készít egy képet, eddig semmi gond vele.
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
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?
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
Én megnézném, hogy httpd -f -vv kapcsolókkal, a szokott user nevében futtatva mit mond. Ububtun kiírja, uogy mihez nyúl, mit nem sikerül megnyitni stb.
- A hozzászóláshoz be kell jelentkezni
Parancssorból futtatva is ugyanaz a jelenség?
- A hozzászóláshoz be kell jelentkezni
Ki fogom próbálni.
* Én egy indián vagyok. Minden indián hazudik.
- A hozzászóláshoz be kell jelentkezni
Elso koron $WEB_INMAGE valtozoban egyel tobb N betu van mint kellene ;)
Masodik korben: milyen shellt hasznalsz? Probaltad bash-sel is?
asd
- A hozzászóláshoz be kell jelentkezni
Annak a plusz N-nek nincs jelentősége (alt= után áll) és a busybox alapján szerintem ash-t.
Nem tudom, a Rpi-n futó busyboxos ash hogy értelmezi a $$-t, az x86-os linuxon lévő a process id-t adja vissza.
- A hozzászóláshoz be kell jelentkezni
Az N nem kell - elírtam (nem másoltam) - javítottam.
Jelenleg a Raspbian /bin/sh -> dash
(A bash -t kipróbálom)
* Én egy indián vagyok. Minden indián hazudik.
- A hozzászóláshoz be kell jelentkezni
bash-sel probaltad mar?
Ki tudja, hogy a busyboxos dash implementacioban mi van benne - vagy rpp mi maradt ki.
asd
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
Ha egy scriptet akarnék debuggolni, ilyesmit próbálnék:
#!/bin/sh
exec 2>/tmp/debug.$$
set -xv
...
- A hozzászóláshoz be kell jelentkezni
Ezt felvésem valahova...
Én a szkript kimenetét szoktam átirányítani.
- A hozzászóláshoz be kell jelentkezni
Ilyesféle trükközés segít akkor is, amikor a scriptet pl. a kernel hívta meg (/sbin/hotplug pl). Vagy az atd/crond, hogy egy tipikusabb példát is mondjak. PS: Persze a stdout-ot is át lehet irányítani, pl:
exec >/tmp/debug.out.$$ 2>&1
set -xv
- A hozzászóláshoz be kell jelentkezni
Ezért akarom felírni. :)
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
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}"
- A hozzászóláshoz be kell jelentkezni
ls -l helyett stat -c "%s" és máris egyszerűbb a dolog
- A hozzászóláshoz be kell jelentkezni
+1
- A hozzászóláshoz be kell jelentkezni
Ha már, akkor minek file-ba írni meg dd meg minden, miért nem írtja egyből stdout-ra a?
- A hozzászóláshoz be kell jelentkezni
+1, nekem is ez jutott eszembe, viszont lusta vagyok megnézni;)
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
Azert erdemes fajlba irni, hogy kesobb is elokeresheto legyen, ha valamiert kell.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
timestamppel probalkoznek
s/timestamp/mktemp/
Semmi sem garantalja, hogy a timestamp egyedi lesz (meg ha nanoszekundumos felbontasu is).
Ha egyszerre tobb keres erkezhet, akkor elmeletileg erkezhetnek egyszerre is (ha Murphy-t kerdezed, akkor biztos, hogy egyszerre fognak erkezni :-)).
- A hozzászóláshoz be kell jelentkezni
En inkabb a ketto kombinaciojat javaslom. Az a baj, hogy az mktemp nem tarol semmit a letrehozasi idorol a fajlnevben, ez pedig kritikus fontossagu lenne egy ilyen alkalmazas eseteben.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
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 hozzászóláshoz be kell jelentkezni
Ö... 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)
- A hozzászóláshoz be kell jelentkezni
Sorredben osztja, de egy fork bomb kb. par sec alatt atcsurrantja a pideket. Tudom, mert pontosan ilyen jellegu hacket kellett hasznalnom valamihez. Szóval de, van ilyen scenario, amikor a PID-ek nem egyediek.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
Aham. Van benne valami. Amíg fut a processz addig nincs vele gond, de a képet könnyen felülírhatja egy másik az általad vázolt helyzetben. (mondjuk topic témájául szolgáló környezetben nehezen tudom elképzelni, hogy gondot okozna ;) )
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
Ez is nagyon hasznos és érdekes információ, de speciel az nem derül ki belőle, hogy megpróbáltál-e debuggolni úgy, ahogy a múltkor javasoltam.
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
> 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.)
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni