Linux за българи: Форуми

Програмиране => Общ форум => Темата е започната от: mrowcp в Sep 05, 2010, 14:58



Титла: bash + php
Публикувано от: mrowcp в Sep 05, 2010, 14:58
Идеята ми е следната: имам няколко bash скрипта и искам да ги интегрирам в php, за да може хора нямащи достъп през ssh да ги ползват.
Принципно знам как се изпълняват, имам няколко php shell-а, както и съм работил малко с webmin, но е кофти когато едитвам php shell, защото кажи-речи налучквам.
Има ли някъде статий или примери за такова нещо?Намерих няколко страници, но никъде няма как примерно се създава празен ред, в който когато се попълни текст да го присвой на някаква променлива и т.н.

П.С. да кажем добавяне на samba юзър или на редове към конфигурационни файлове.


Титла: Re: bash + php
Публикувано от: morbid_viper в Sep 05, 2010, 22:20
да ти кажа честно не разбрах какво точно искаш да направиш… дай точно задачката, която си си поставил…


иначе bash скриптовете в php се извикват както всяка друга системна команда чрез system();


Титла: Re: bash + php
Публикувано от: mrowcp в Sep 05, 2010, 23:57
да ти кажа честно не разбрах какво точно искаш да направиш… дай точно задачката, която си си поставил…


иначе bash скриптовете в php се извикват както всяка друга системна команда чрез system();

Код
GeSHi (Bash):
  1. #!/bin/bash
  2. status=`/usr/local/etc/rc.d/isc-dhcpd status`
  3. ############
  4. echo -n "Enter hostname: "
  5. read host
  6. echo -n "Enter MAC: "
  7. read mac
  8. echo -n "Enter IP: "
  9. read ip
  10. echo -n "Restart dhcp(y/n): "
  11. read dhcp
  12. echo "host $host { " >> dhcpd.conf
  13. echo "hardware ethernet $mac;" >> dhcpd.conf
  14. echo "fixed-address $ip;" >> dhcpd.conf
  15. echo "}" >> dhcpd.conf
  16. if [ $dhcp = y ];then
  17. echo "/usr/local/etc/rc.d/isc-dhcpd restart"
  18. echo "$status"
  19. else
  20. echo "Done"
  21. fi

да го направя да може да работи в php, като примерно вместо да пита за $MAC, $IP и $host, може да са полета в които се попълва и да има един бутон ADD който да добавя нещата в dhcpd.conf-a :)


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


Титла: Re: bash + php
Публикувано от: mrowcp в Sep 06, 2010, 16:41
Мерси, отново :) за изчерпателния отговор.Евала, че ти се занимава да пишеш толкова  [_]3
Ще препрочета още 2,3 пъти поста ти :) и ще пробвам да сътворя нещо.


Титла: Re: bash + php
Публикувано от: neter в Sep 06, 2010, 17:23
Поради обзела ме инерция написах междинния скрипт като частен случай, а трябва да обхваща всички случаи, тъй като той ще извиква всичките ти скриптове, а не във всички скриптове ще имаш 3 параметъра към извикания скрипт, и не във всички ще имаш параметри hostname, mac и ip, така че ето ти по-универсален междинен скрипт
Код
GeSHi (Bash):
  1. #!/bin/bash
  2.  
  3. scripts_path='/пълен/път/до/папката/със/скриптовете'
  4. cache_file='/пълен/път/до/файла/с/данните'
  5. tmp_file='/пълен/път/до/копие/на/файла/с/данните'
  6.  
  7. cp $cache_file $tmp_file
  8. rm $cache_file
  9.  
  10. cat $tmp_file | while read i
  11. do
  12.   script=`echo "$i" | /usr/bin/cut -d'|' -f1`
  13.  
  14.   string=`echo "$i" | sed 's/ /INTERVAL/g'`
  15.   array=$(echo $string | tr '|' '\n')
  16.  
  17.   data=''
  18.   z=0
  19.   for y in ${array[@]}; do
  20.      if [[ $z -gt 0 ]]; then
  21.         data="$data '`echo $y | sed 's/INTERVAL/ /g'`'"
  22.      fi
  23.      z=$(($z+1))
  24.   done
  25.  
  26.   $scripts_path/$script $data
  27. done

редакция: Много съм разсеян днес - вчера бях на сватба [_]3