Има няколко начина за постигане на това, което искаш, но аз ще ти предложа един - не интегрирай shell скриптовете в публичната част, а ги остави като две самостоятелно изпълняващи се системи, черпещи информация една от друга. По-подробно описано, напиши си публичната част, в която да се събират данните, нужни на shell скриптовете (от по-горния пример, задължително hostname, MAC и IP, а можеш да си записваш и някаква допълнителна информация, като потребител и т.н.) и записвай събраната информация в някакви файлове (намисли си удобен формат на данните вътре). Пусни shell скриптовете да се изпълняват през даден период от crontab, като изчитат информацията в буферните файлове, за да получат нужните данни за изпълнението. Така си решаваш някои ядове със сигурността, не се занимаваш с динамични превключвания между системни потребители, получаваш разделение на кода, което внася яснота при администриране, и в някои случаи можеш да си намалиш натоварването от изпълнението на цялата схема.
Ето пример в код. Първо, потребителска част за събиране на данни:
GeSHi (PHP):
<?php
$script = 'име на shell скрипта, който ще изпълнява това';
$cachefile = 'име на файла с данните';
if ($_POST) {
$data = $script.'|'.$_POST['hostname'].'|'.$_POST['mac'].'|'.$_POST['ip']."\n";
file_put_contents($cachefile, $data, FILE_APPEND);
}
?>
<form method="post" action="">
Hostname: <input type="text" name="hostname"><br />
MAC: <input type="text" name="mac"><br />
IP: <input type="text" name="ip"><br />
<input type="submit" value="Изпрати">
</form>
Според това, което съм въвел в променливата $data, данните във файла ще се записват във формат
скрипт|hostname|mac|ip
като всеки нов запис ще отива на нов ред. С това, публичната част е готова.
За изпълнението на скриптовете имаш два варианта - да сложиш всички shell скриптове в crontab-а на нужния ти потребител (в твоя пример ти трябва crontab-а на root, тъй като действията вътре го изискват), или да ползваш междинен shell скрипт, който да се върти от crontab и който да извиква скриптовете, според съдържанието във файла с данните. Ще ти покажа пример с втория вариант. Код за междинен скрипт
GeSHi (Bash):
#!/bin/bash
scripts_path='/пълен/път/до/папката/със/скриптовете'
cache_file='/пълен/път/до/файла/с/данните'
tmp_file='/пълен/път/до/копие/на/файла/с/данните'
cp $cache_file $tmp_file
rm $cache_file
cat $tmp_file | while read i
do
script=`echo "$i" | /usr/bin/cut -d'|' -f1`
hostname=`echo "$i" | /usr/bin/cut -d'|' -f2`
mac=`echo "$i" | /usr/bin/cut -d'|' -f3`
ip=`echo "$i" | /usr/bin/cut -d'|' -f4`
$scripts_path/$script "$hostname" "$mac" "$ip"
done
Този скрипт ще извиква всички скриптове, описани във файла с данните от публичната част, в реда, в който са описани във файла с данните. Копирам файла с данните на ново място и изчиствам стария, за да не става объркване на данните, ако по време на изпълнението на скриптовете, някой добави нова информация от публичната част. Така скриптовете ще си работят върху последно взетата информация, а нововъведените ще се изпълнят при следващото завъртане на crontab-а.
Остана да редактираш твоите скриптове да не ползват read, а да ползват променливите $1, $2, $3 и т.н. (зависи колко данни записваш на един ред) - тези променливи отговарят на позициите на подадена информация към скрипта от реда при изпълнението му
./script $1 $2 $3 ...
Трябва да изчистиш скриптовете си от изкарването на информация на екрана, тъй като няма да се извикват ръчно и тази информация се явява излишна. Може да я насочиш да се записва в някакъв лог.
Трябва да имаш в предвид, че в този пример използвах права черта за разделение на данните в редовете във файла с данните. Този разделител е удачен за примера, който показа (във въведените данни не се очакват прави черти), но в останалите ти скриптове може да не е удачен, така че прецени какъв разделител ще действа универсално за всичките ти скриптове (може, и е препоръчително, да не е от един символ). Ако променяш разделителя, трябва да го промениш в PHP файла и в междинния shell скрипт.
Сложи завъртането на crontab-а да става на не по-малък интервал, от очаквано нужния за изпълнението на скриптовете, за да не става застъпване на изпълненията (освен, ако нямаш полза от тези застъпвания). Ако искаш в публичната част да се вижда какво се е случило при изпълнението на скриптовете, укажи на скриптовете да записват изходните си данни в лог файл, съдържанието на който да визуализираш в някаква страничка в публичната част. Колко още може да се усъвършенства тази система е въпрос на въображение