Fórum Root.cz
Hlavní témata => Software => Téma založeno: beer 25. 01. 2016, 13:40:20
-
ahoj, napsal jsem si script, který by mi měl mojí ipv4 adresu odeslat na github, script funguje ok, chtěl jsem ale, aby se mi spuštěl každý 5 minut, mám v /etc/cron.d/ipv4-public
5 * * * * /mnt/sdcard/slozka/public_ipv4.sh >/dev/null 2>&1
Script se ale nespustí, co dělám špatně? Je potřeba to nějak ještě povolovat? Jedná se Turris s openwrt.
public_ipv4.sh obsahuje:
#!/bin/sh
sleep 20
cd /mnt/sdcard/mnt/sdcard/slozka/
wget http://ipinfo.io/ip -qO - > /mnt/sdcard/mnt/sdcard/slozka/ipv4.txt
date > /mnt/sdcard/slozka/public.ipv4.log
git init
git add *
git commit -m "$(date)"
git remote add origin git@github.com:uzivatelskejmeno/slozka.git
git push -u origin master
exit 0
Když script public_ipv4.sh spustím ručně, tak se správně na githubu objeví moje ip adresa a čas v public.ipv4.log, ale cron se mi ne a ne spouštět.
-
To není každých pět minut, ale každou pátou minutu v hodině. Tedy když budou hodiny ukazovat *:05. Tu první část je potřeba změnit na */5. Tedy když jsou minuty dělitelné pěti.
-
To není každých pět minut, ale každou pátou minutu v hodině. Tedy když budou hodiny ukazovat *:05. Tu první část je potřeba změnit na */5. Tedy když jsou minuty dělitelné pěti.
Díky, ovšem bohužel se nespouští ani každoupátou minutu v hodině, ani každých 5 minut. Nyní jsem upravil na */5, což by mělo být tedy každých 5 minut. Umí cron pracovat se symlinky? Ten soubor /etc/cron.d/ipv4-public je symbolickým odkazem souboru /mnt/sdcard/slozka/etc/cron.d/ipv4-public, práva má nastavená na 777.
-
A běží démon cronu?
-
A běží démon cronu?
ps |grep cron
4917 root 832 S cron
11438 root 1528 S grep cron
Běží, alespoň myslím (4917).
-
A ziral jste do logu (asi syslog), jestli tam cron nenadava?
-
Nevím, jaký cron je v OpenWRT, ale některým implementacím je potřeba poslat signál, že si mají přenačíst definiční soubory. Také se mi zdá divný formát souboru cronu – máte to pod cron.d, tedy je to globální cron, ale nikde tam nevidím jméno uživatele, pod kterým má ten skript běžet. Další věc je, že skript z cronu se spouští s jiným nastavením proměnných prostředí, např. PATH – ve skriptu máte příkazy wget nebo git uváděné bez cesty, takže je možné, že se nenajdou. Pokud si chcete ověřit, že se skript alespoň spouští, dejte si hned na začátek touch na nějaký soubor v /tmp. Takhle nevíte, zda se skript vůbec nespouští, nebo zda selže.
A také se podívejte do logu, pokud je něco špatně v cronu (chybná konfigurace), mělo by se to někde objevit.
-
root@turris:~# cat /var/log/messages | grep cron | grep ipv4
2016-01-25T14:11:09+01:00 info cron[4917]: (*system*) BAD FILE MODE (/etc/cron.d/ipv4-public)
-
root@turris:~# cat /var/log/messages | grep cron | grep ipv4
2016-01-25T14:11:09+01:00 info cron[4917]: (*system*) BAD FILE MODE (/etc/cron.d/ipv4-public)
Proč kdekdo místo crontabu používá cron? Ten aspoň při uložení cronu řekne, co se mu nelíbí.
-
Nevím, jaký cron je v OpenWRT, ale některým implementacím je potřeba poslat signál, že si mají přenačíst definiční soubory. Také se mi zdá divný formát souboru cronu – máte to pod cron.d, tedy je to globální cron, ale nikde tam nevidím jméno uživatele, pod kterým má ten skript běžet. Další věc je, že skript z cronu se spouští s jiným nastavením proměnných prostředí, např. PATH – ve skriptu máte příkazy wget nebo git uváděné bez cesty, takže je možné, že se nenajdou. Pokud si chcete ověřit, že se skript alespoň spouští, dejte si hned na začátek touch na nějaký soubor v /tmp. Takhle nevíte, zda se skript vůbec nespouští, nebo zda selže.
A také se podívejte do logu, pokud je něco špatně v cronu (chybná konfigurace), mělo by se to někde objevit.
Doplněn uživatel root, uvidíme, jestli bude OK, ve scriptu je uvedeno
cd /mnt/sdcard/mnt/sdcard/slozka/
tak by to mělo být ok, nebo mám tomu cronu zadávat tu cestu?
-
oprava
cd /mnt/sdcard/slozka/
-
root@turris:~# cat /var/log/messages | grep cron | grep ipv4
2016-01-25T14:11:09+01:00 info cron[4917]: (*system*) BAD FILE MODE (/etc/cron.d/ipv4-public)
http://www.cyberciti.biz/faq/unix-linux-cron-bad-file-mode-error/
-
root@turris:~# cat /var/log/messages | grep cron | grep ipv4
2016-01-25T14:11:09+01:00 info cron[4917]: (*system*) BAD FILE MODE (/etc/cron.d/ipv4-public)
To jsou ta oprávnění 777. To asi není dobrý nápad nechat kohokoli editovat ten soubor, když tam může napsat, že se má jeho příkaz spustit pod rootem…
tak by to mělo být ok, nebo mám tomu cronu zadávat tu cestu?
Jde o cesty k těm programům, které v tom skriptu spouštíte. Když máte ve skriptu uveden příkaz wget, znamená to, že se projdou adresáře uvedené v $PATH a hledá se v nich spustitelný soubor wget. Ten, který se najde jako první, se spustí. Třeba u mne je to /usr/bin/wget (zjistíte to příkazem which wget). Jenže pokud při spuštění v tom cronu nebude /usr/bin uvedeno v $PATH, wget se nenajde. Proto je lepší v tom skriptu uvádět plné cesty k programům.
-
kde najdu plnou cestu k programu cd?
which cd mi nic nenajde...
-
Príkazy shellu nemajú cestu
cd je príkaz shellu
-
#!/bin/sh
cd /mnt/sdcard/slozka/
/usr/bin/wget http://ipinfo.io/ip -qO - > /mnt/sdcard/slozka/ipv4.txt
/bin/date > /mnt/sdcard/slozka/public.ipv4.log
/usr/bin/git init
/usr/bin/git add /mnt/sdcard/slozka/*
/usr/bin/git commit -m "$(date)"
/usr/bin/git remote add origin git@github.com:jiri001meitner/slozka.git
/usr/bin/git push -u origin master
exit 0
*/5 * * * * root /mnt/sdcard/slozka/public_ipv4.sh >/dev/null 2>&1
Pořád nefunguje přes cron
-
zkusím
*/5 * * * * root cd /mnt/sdcard/slozka/ && sh /mnt/sdcard/slozka/public_ipv4.sh >/dev/null 2>&1
bude to takto OK?
-
Pořád nefunguje
-
Kristova noho... nejede mi auto, heeeelp!!! Už si opravil ty práva?! A co přesně je nepochopitelného na tom, abys uváděl celou cestu k příkazům (např. /bin/sh), a k čemu je tam to cd?
-
nyní už funguje v té poslední konfiguraci, co jsem sem dával. (po /etc/init.d/cron stop a /etc/init.d/cron start). To cd je tam kvůli gitu, musí se volat z té složky. Práva jsou 0600.
-
Proč používáš cron a ne crontab?
-
Proč používáš cron a ne crontab?
Aby se to hůř debugovalo... ;D
-
Proč používáš cron a ne crontab?
Na turrisu je sice taky crontab, ale co jsem koukal, tak všechny systémové věci co se automaticky aktualizují jsou ve složce /etc/cron.d/ tak abych zachoval konzistentní nastavení.
Navíc jsem z jiného projektu zvyklý řešit automatické aktualizace i cron souborů přes git, proto mi to vyhovuje lépe. Nedokážu si moc představit hromadnou změnu crontabu, kde je třeba x položek, je pro mne snažší změnit jeden soubor. Je to pro mne lepší i pro obnovení zálohy.
-
například přidáním
/usr/bin/git push -u origin master || /usr/bin/git pull --no-edit
mohu změnit soubor cronu rovnou přes webové rozhraní gitu. Jelikoš funguje, tak mohu zakomentovat /bin/date > /mnt/sdcard/slozka/public.ipv4.log a tento soubor smazat, pak stačí jednou spustit git ls-files --deleted | xargs git rm
a odteď aktualizovat veškerou funkcionalitu ohledně tohoto scriptu včetně spouštění z githubu.
-
zkusím
*/5 * * * * root cd /mnt/sdcard/slozka/ && sh /mnt/sdcard/slozka/public_ipv4.sh >/dev/null 2>&1
bude to takto OK?
Není to O.K. Pokud něco nefunguje, výstup se přesměruje do souboru. Tedy na konci místo >/dev/null 2>&1 se píše >/tmp/myDebug.log 2>&1 . Až se to odladí, pak snad. Když si spouštění stěžuje v /dev/null (včetně chybového výstupu), špatně se ta chyba hledá.
-
Chybový výstup bych po odladění nepřesměrovával do souboru, tam si ho nikdo nevšimne, ale nechal bych ho psát na standardní výstup. Cron jde většinou nakonfigurovat tak, že pokud proces vypíše něco na standardní výstup, pošle to na zadaný e-mail. Tak se o chybě dozvíte hned, a ne až se vám někdo bude říkat, že má pocit, jako by ten automat nefungoval a vy teprve začnete shánět ten soubor.
-
Chybový výstup bych po odladění nepřesměrovával do souboru, tam si ho nikdo nevšimne, ale nechal bych ho psát na standardní výstup. Cron jde většinou nakonfigurovat tak, že pokud proces vypíše něco na standardní výstup, pošle to na zadaný e-mail. Tak se o chybě dozvíte hned, a ne až se vám někdo bude říkat, že má pocit, jako by ten automat nefungoval a vy teprve začnete shánět ten soubor.
Tak ono to funguje OK, takže nepotřebuju chybový výstup. Nastavil jsem si ve skriptu /bin/date > /tmp/public.ipv4.log, prostým ověřením času tohoto souboru zjistím, že cron proběhl OK. Nepotřebuji posílat e-mailem, musel bych do openwrt instalovat program pro posílání e-mailů a to mi připadá zbytečné. Jinak souhlasím, že pro debuggování je to užitečné sledovat, ať už v souboru, nebo na standardním chybovém výstupu.
-
kdyz nemas nastaveny email, tak to jde do souboru /root/dead.letter
-
kdyz nemas nastaveny email, tak to jde do souboru /root/dead.letter
To není žádoucí - interní paměťové úložiště je potřeba u turrisu šetřit - omezený počet přepisů, mají to i v manuálech, to už je lepší to směřovat do souboru v tmp, který je v ram.
-
ten dead.letter neni az zas tak velkej, pokud mu tam nepribude milion radku kazdych pet minut
jinak ho muzes presmerovat do tmpfs
-
No, právě že by mi pořád přibívaly chyby i v případě úspěšného průběhu, a to tyto:
warning: templates not found /usr/share/git-core/templates
Reinitialized existing Git repository in /mnt/sdcard/public-ipv4-turris/.git/
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
fatal: remote origin already exists.
Everything up-to-date
Branch master set up to track remote branch master from origin.
-
No, právě že by mi pořád přibívaly chyby i v případě úspěšného průběhu, a to tyto:
[...]
pokud script pousteny cronem neco zobrazi pri uspesnem prubehu je to spatne, nema zobrazovat absolutne nic
pokud uzivatel pouziva stejny skript i pro pousteni rucne, kdy chce zobrazovat i uspesny prubeh, muze jednoduse ve skriptu detekovat jestli je pousteno uzivatelem nebo cronem a podle toho zobrazovat nebo nezobrazovat...
a error nechat zobrazovat(/preposilat/ukladat) vzdy...
-
Já tyhle chyby za chyby nepovažuji, warning ohledně templates mne netrápí, to, že je up to date znamená, že nebyla detekována změna a tudíž není co commitnout, nepotřebuju to dělat složitější, když to funguje, jak má, chybový výstup cronu mohu posílat do souboru v /tmp/ (kam jsem si to dneska nastavil, abych vám ty chyby napsal). Proč bych měl dělat skript složitější? Pro to není přece žádný důvod, aby tam byly nějaké detekce pro to, jestli je to spuštěné uživatelem nebo ručně. Kdo by chtěl, může se inspirovat a vymyslet lepší způsob. Účelem je připojení se na router i když se změní ip adresa.
https://github.com/jiri001meitner/public-ipv4-turris
připojuji se například z keyboxu přes https a webový prohlížeč na rhcloudu takto:
v bash profilu mám
alias ssh_ipv4="~/app-root/data/ssh_ipv4.sh"
a v souboru ~/app-root/data/ssh_ipv4.sh
ssh root@$(curl "https://raw.githubusercontent.com/jiri001meitner/service.meitner.cz/master/ipv4.txt") -C -F ~/app-root/data/ssh/ssh_config -p číslo portu
v ~/app-root/data/ssh/ mám samozřejmě klíče chráněné passphrase.
-
Tak ono to funguje OK, takže nepotřebuju chybový výstup.
To je jak takové ty poslední věty před smrtí… Chyby se nelogují proto, že by se lidé chtěli kochat tím, jak programy krásně nefungují. Logují se proto, že zkušenosti ukazují, že něco, co funguje, se může docela snadno rozbít. A pak je dobré se o tom z výpisu chyb dozvědět. Takže chybový výstup potřebuje, abyste se dozvěděl, až to fungovat OK přestane.
Nastavil jsem si ve skriptu /bin/date > /tmp/public.ipv4.log, prostým ověřením času tohoto souboru zjistím, že cron proběhl OK.
Vy na ten router každých pět minut polezete a budete kontrolovat čas toho souboru? Přece od toho máme počítače, aby rutinní úlohy dělaly za nás.
Nepotřebuji posílat e-mailem, musel bych do openwrt instalovat program pro posílání e-mailů a to mi připadá zbytečné.
Pokud vám je jedno, zda se ta cron úloha správně provádí nebo ne, mohl jste si ušetřit čas s jejím vytvářením.
No, právě že by mi pořád přibívaly chyby i v případě úspěšného průběhu, a to tyto:
Skutečné chyby a varování je dobré opravit, informační hlášky na standardní výstup je možné potlačit nebo přesměrovat jinam (třeba do /dev/null). Já jsem v komentáři psal o přesměrování chybového výstupu.
nepotřebuju to dělat složitější, když to funguje, jak má, chybový výstup cronu mohu posílat do souboru v /tmp/
Problém je v tom, že do /tmp/ ten chybový výstup budete posílat i tehdy, když to nebude fungovat, jak má. Jednoduché už jste to měl, a výsledkem bylo, že jste se musel na fóru ptát, co děláte špatně.
-
Chyby se nelogují proto, že by se lidé chtěli kochat tím, jak programy krásně nefungují. Logují se proto, že zkušenosti ukazují, že něco, co funguje, se může docela snadno rozbít. A pak je dobré se o tom z výpisu chyb dozvědět. Takže chybový výstup potřebuje, abyste se dozvěděl, až to fungovat OK přestane.
Moc pěkně řečeno, s tím se dá jen souhlasit. Pokud přestane fungovat a já se díky tomu na router nepřipojím, tak je mi log k ničemu, že.
Jakmile se připojím, tak zjistím, proč neproběhlo - nepřidělená ip z wan, selhání rezervní konektivity, která tam je nastavená (wi-free), apod.
Nemám důvod tam lozit každých pět minut a kotrolovat, jestli skript pracuje ok. Pracuje OK, bude pracovat i dál. Při každé změně konfigurace je potřeba otestovat. Poslední ip adresu mám přidělenou od poskytovatele déle než rok, předpoklad že se změní není veliký.
Nicméně chybový výstup z cronu loguji nyní do /tmp/public.ipv4.cron.log
Pokud vám je jedno, zda se ta cron úloha správně provádí nebo ne, mohl jste si ušetřit čas s jejím vytvářením.
Něco takového bylo někde napsáno? To je dedukováno z toho, že zavrhuji bobtnající chybový výstup? Nebo spamování e-mailem v čase každého spuštění úlohy?
Myslím, že jste nepochopil, že to, že úloha skončí chybou když se nezmění ip adresa - neproběhne díky tomu commit. To není chyba, to je záměr! Tam žádné skutečné chyby, které mají vliv na funkčnost, v tuto chvíli nejsou.
Problém je v tom, že do /tmp/ ten chybový výstup budete posílat i tehdy, když to nebude fungovat, jak má.
To není problém, to je záměr. Tam to snadno najdu když nebude fungovat a jsou tam logy od všeho možného. Navíc opravdu nehodlám ničit router za 12 tisíc tím, že tam každých pár minut budu přepisovat pamět.
Jednoduché už jste to měl, a výsledkem bylo, že jste se musel na fóru ptát, co děláte špatně.
Ano, chyba byla nalezena, částečně s pomocí fóra, částečně díky googlování a metodám typu pokus omyl - chyběl mi uživatel v cronu, a taky jsem tam musel zněnit složku, odkud cron volá git, další věc byla, že i na fóru pro turris mi bylo řečeno, že to není windows a že není potřeba nic jiného dělat, aby se změny v cronu projevily. No, nebyla to pravda, pokud se neudělá alespoň /etc/init.d/cron reload, tak se změny neprojeví.
-
Jakmile se připojím, tak zjistím, proč neproběhlo
Jenže nejdřív musíte zjistit, že to neproběhlo.
Pracuje OK, bude pracovat i dál.
To je tak naivní… Obzvlášť pikantní je, že jste předevčírem neuměl cron ani základně nastavit, a dnes tvrdíte, že se to nemůže rozbít.
Při každé změně konfigurace je potřeba otestovat.
A také při každé změně verze, a to na obou stranách, při každé změně v síti (bude vám to hlásit ISP?). A dokonce i při každé změně času, protože to může přestat fungovat prostě plynutím času (skončí platnost certifikátu, registrace domény…).
Něco takového bylo někde napsáno? To je dedukováno z toho, že zavrhuji bobtnající chybový výstup? Nebo spamování e-mailem v čase každého spuštění úlohy?
Plyne to z toho, že chybový výstup přesměrováváte do souboru, který musíte ručně kontrolovat. Chybový výstup funkční aplikace nebobtná. Chybový výstup funkční aplikace je prázdný, a bobtnat začne teprve ve chvíli chyby – a to je přesně ten okamžik, který vás zajímá. Ke spamování e-mailem v čase každého spuštění úlohy nedochází, přece píšete, jak vám to správně funguje, tak nemůže být nic na chybovém výstupu.
Myslím, že jste nepochopil, že to, že úloha skončí chybou když se nezmění ip adresa - neproběhne díky tomu commit. To není chyba, to je záměr!
Myslím, že vy jste nepochopil, že tam může být milion jiných chyb.
Tam žádné skutečné chyby, které mají vliv na funkčnost, v tuto chvíli nejsou.
Což neříká vůbec nic o tom, jak to bude za deset minut.
Navíc opravdu nehodlám ničit router za 12 tisíc tím, že tam každých pár minut budu přepisovat pamět.
To po vás také nikdo nechce.
Ano, chyba byla nalezena, částečně s pomocí fóra, částečně díky googlování a metodám typu pokus omyl - chyběl mi uživatel v cronu, a taky jsem tam musel zněnit složku, odkud cron volá git, další věc byla, že i na fóru pro turris mi bylo řečeno, že to není windows a že není potřeba nic jiného dělat, aby se změny v cronu projevily. No, nebyla to pravda, pokud se neudělá alespoň /etc/init.d/cron reload, tak se změny neprojeví.
Tohle všechno jste nevěděl před dvěma dny, a za ty dva dny jste se toho naučil tolik, abyste mohl tvrdit, že když to funguje teď, bude to fungovat už navěky? Sebevědomí vám teda rozhodně nechybí.
Dělejte jak umíte. Rady od lidí, kteří cron používají už desítky let, jste dostal.
-
Nikdo vám nebrání kód na githubu forknout a ukázat, že to umíte lépe. Pro mé účely to je takto OK, ale pokud vaše řešení bude lepší, rád se nechám inspirovat.
-
odstranil jsem cesty v souboru, a funguje, dal jsem za gitové příkazy 2>/dev/null a nyní je již chybový výstup bez záznamů. Nyní by to mělo logovat jen případné chyby, se kterými se nepočítá.
-
neber si to osobne... proste skript v cronu NEMA zobrazovat NIC, pokud nejde o chybu, jakmile zobrazi chybu NEMA se hodit do null, ale do mailu roota (pripadne do souboru co root bude kontrolovat rucne kdyz se 'boji' mailu), dela se to tak proto se pouze error na tebe bafne, pouze error bude 'plnit logy' a nedela se to pro pripady ze vse funguje, ale prave pro pripady ze neco nezafungovalo aby jsi se o tom snadno a v ramci moznosti hned dozvedelel...
btw: v pripade chteneho logovani i uspechu a/nebo vetsiho mnozstvi informaci: man logrotate (http://linux.die.net/man/8/logrotate)
v pripade ze by jsi chtel pri rucnim pusteni zobrazovat i informace ale pri cron ne, neni to nic komplikovaneho, jednoduse napr.
#!/bin/sh
tty -s && runuser="yes" || runcron=">/dev/nul"
[ $runuser ] && echo "ted se bude delat nejakej_prikaz"
nejakej_prikaz ${runcron}
-
Rozumím těmto argumentům, aktuálně mám nastaveno, že chybuvý výstup je v cronu prázdný, tak snad je to OK. Ručně spouštět nepotřebuji. No, je to script na hraní, jehož účelem je prostě poslat ip adresu, na kterou se můžu připojit. Jsou ale i osvědčené jiné metody (dynamické dns), které jsou standardizované, jen jsem chtěl to vyzkoušet jinak, třeba to bude hodit někomu, kdo nemá možnost použít dynamické dns. Zaregistroval jsem se na noip.com a vyzkouším, jestli je to lepší, nežli mé řešení, tak svůj skript smažu. Ve skriptu nemuseli být nakonec ty cesty k těm programům, je funkční i bez nich, proto jsem je odstranil.
Aktuální funkční (u mne) konfigurace
#!/bin/sh
# change directory to local turris git repository
cd /mnt/sdcard/public-ipv4-turris/
#current public ipv4 address
#/usr/bin/
ip addr show br-wan | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | head -n 1 1> /mnt/sdcard/public-ipv4-turris/ipv4.txt || wget http://ipinfo.io/ip -qO - 1> /mnt/sdcard/public-ipv4-turris/ipv4.txt || curl ifconfig.co 1> /mnt/sdcard/public-ipv4-turris/ipv4.txt || curl -s checkip.dyndns.org | sed -e 's/.*Current IP Address: //' -e 's/<.*$//' 1> /mnt/sdcard/public-ipv4-turris/ipv4.txt
#last run log
date > /tmp/public.ipv4.log
#remote upload ipv4 changes
git init 2>/dev/null
git add /mnt/sdcard/public-ipv4-turris/* 2>/dev/null
git commit -m "$(date)" 2>/dev/null
git ls-files --deleted | xargs git rm 2> /dev/null
git push -u origin master 2>/dev/null || /usr/bin/git pull --no-edit
exit 0
Cron jsem si nastavil logování chyb do souboru v /tmp a nastavil jsem si to na 2 minuty. Log je čistý, jenom když proběhne git pull, tak mi zapíše zprávu do souboru /tmp/public.ipv4.log.cron, což tak mám schválně.
*/02 * * * * root cd /mnt/sdcard/public-ipv4-turris && sh /mnt/sdcard/public-ipv4-turris/public_ipv4.sh 2>>/tmp/public.ipv4.log.cron
Nekamentujte mne, že to není přesně podle vašich představ. IP adresa se primárně zjišťuje interně z rozhraní, u ostatních by to takto nefungovalo, protože budou mít jiný název rozhraní, nebo tam mohou mít lokální adresu. V případě, když selže zjištění adesy, tak se zjišťuje z několika zdrojů přes internet. Rád se ale přiučím.