Autor Zpráva
JanMatoušek
Profil
Ahoj, nevím jestli to dávám do správného vlákna, ale nevím kam jinam.

V shellu se extra nevyznám, ale sepsal jsem si jednoduchý script na asynchroní spouštění php soborů.

Cílem je, že chci spouštět php scripty pomocí cronu, zařazené do jednotlivých složek.

dejme tomu, že si udělám složky
cron.1min
cron.1day

v každé složce bude soubor php.cronner.sh, který zajistí asynchorní spouštění php scriptů

vím, že v cmd lze napsat php myScript.php &, ale když to tak udělám v tom shell scriptu, tak se scripty provedou stejně postupně.

zde je shell:
#!/bin/bash 
#executes all php scripts in same directory 

basedir=$(dirname $0) 

for entry in "$basedir"/* 
do 
  ext=$(echo $entry |awk -F . '{if (NF>1) {print $NF}}') 

  if [ 'php' == $ext ] 
  then 
    php $entry &; 
  fi 
      
done  
Karel N.
Profil
Jak jsi přišel na to, že to nefunguje? :). Dej jen na konec skriptu (za done) ještě wait, aby se počkalo na jejich dokončení a mohl jsi za to dát nějaké debugovací příkazy

Lze ještě použít GNU parallel, který má trochu přehlednější syntaxi:

parallel 'php {}' ::: *.php
JanMatoušek
Profil
No, když si tam dám 2 PHP scripty (co logují čas startu a čas konce) a pustím to přes konzoli, tak mi ty scripty lognout:
20:50:00 -start první
20:50:05 -konec první
20:50:06 -start druhý
20:50:10 -konec druhý

což je vidět, že to šlo za sebou
Karel N.
Profil
dej si do toho skriptu před řádek se spuštěním php něco podobného echo $entry, věřím tomu, že se ti echa provedou dřív než to php. Není problém s tvoji aplikací v php? Nevisí ti to třeba kvůli zámku souborů třeba na session?

Zkus si dát místo php něco jako sleep 1 & a skript ti skončí běh cca za vteřinu, tj. vše se spustilo parallelně.
JanMatoušek
Profil
No je možný, že je to tím php scriptem, protože jsem zkoušel i php treads a narazil jsem na stejný problém:-D

v php mám na test toto:
<?php
$start = new DateTime();
sleep(2);
$end = new DateTime();


$file = __DIR__ . '/test2.txt';

if(!file_exists($file)){
    $filesource = fopen($file, 'w');
    fclose($filesource);
}

$current = 'test2 ended' . "\r\n";
$current .= $start->format('d/m/Y H:i:s') . "\r\n";
$current .= $end->format('d/m/Y H:i:s');

file_put_contents($file, $current);

ale oba php soubory zapisují do jiného souboru.

PS: tak opravdu to bude tím PHP, ten sleep to potvrdil

PS2: když do PHP scriptu 1 dám sleep(5) a do druhého sleep(4), tak to jede 9s. Tak čím to může být? :-)
Karel N.
Profil
s tímhle problémem jsem se nesetkal, v tom ti víc nedokážu naslepo poradit. Něco to tam bude blokovat. Nejprve bych prověřil, které soubory jsou otevřeny php skriptem a jestli na nich není zámek, poté bych zkontroloval nastavení php-fpm/apache, jestli je správně nakonfigurovaný pro spouštění více instancí.
JanMatoušek
Profil
Dobře. I tak díky za tipy. Pokud to rozchodím, dám info čím to bylo.
JanMatoušek
Profil
Zkoušel jsem to u sebe na win a když jsem ten script dal na server, kde je debian, tak to házelo errory, po opravení errorů to funguje jak na win, tak na debianu

Takže, pokud by někdo chtěl využít tento způsob cronu, tak tady je script:
#!/bin/bash
#executes all php scripts in same directory 

basedir=$(dirname $0);

for entry in "$basedir"/* ;
do 
  ext=$(echo $entry |awk -F . '{if (NF>1) {print $NF}}');

  if [ "$ext" = "php" ]
  then
    php $entry &
  fi
     
done

wait           
juriad
Profil
JanMatoušek:
Mohl bys to zjednodušit:
for entry in "$basedir/*.php"; do
  php "$entry" &
done
wait

A to zjištění přípony, spouštět kvůli tomu dva další programy :-) Lze to napsat přímo v shellu:
ext="${entry##*.}"; # odsekne od začátku nejdelší úsek tvaru *., tedy ponechá jen poslední příponu
JanMatoušek
Profil
Aha, super:-)

Jak říkám, moc se v shellu nevyznám, Takže jsem vygooglil, jak projet adresář a jak kontrolovat příponu:-) To že bych mohl projet adresář s danou příponou, to mě nenapadlo :-)
juriad
Profil
JanMatoušek:
Od toho je diskuse, víc lidí víc ví.

Ještě poznámka, je dobré všechny proměnné obalit do uvozovek, protože co kdyby proměnná obsahovala mezeru?
Na druhou stranu je to tvůj server a pokud jsi rozumný, tak zajistíš, že tam ty mezery nebudou.
[adam@judy ~]$ soubory="a b c"
[adam@judy ~]$ cat $soubory 
cat: a: No such file or directory
cat: b: No such file or directory
cat: c: No such file or directory
[adam@judy ~]$ cat "$soubory"
cat: a b c: No such file or directory
JanMatoušek
Profil
jen mi to nebralo tu hvězdičku jako zástupný znak, takhle už jo:
for entry in "$basedir/"*".php"; do
  php "$entry" &
done
wait



Jo super, díky za vysvětlení:-)

Vaše odpověď


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: