Помогите оптимизировать bash файл

Тема в разделе "Raspberry Pi", создана пользователем user999, 3 мар 2017.

  1. user999

    user999 Гик

    В общем предистория.
    Решил создать систему перезагрузки 3-х плат ардуино-мега, если давно не отвечали
    На малинке поднят апаче.
    Малинка каждые 10 сек. обращается к php страничке у себя же на сервере.
    Сервер проверяет как себя чувствуют ардуинки и дает некий ответ.
    Как прочитать ответ сервера файлом bash я не нашел возможности, поэтому решил писать в файл информацию, а из bash читать эти файлы.
    Если файл не пустой, то надо перезагрузить ардуино, следовательно подаем питание на определенный пин, ждем секунду, отключаем питание, затираем файл.
    Как оптимизировать bash файл циклом, а может есть другой вариант не с файлами, а с ответом сервера?
    Код (Bash):
    #!/bin/bash
    while true; do
    curl "http://localhost/data.php?action=status"
    sleep 2
    pin17=`cat /home/pi/rebootpin17`
    pin27=`cat /home/pi/rebootpin27`
    pin22=`cat /home/pi/rebootpin22`
    if [ "$pin17" -eq "1" ]
    then
    echo "1" > /sys/class/gpio/gpio17/value
    sleep 1  
    echo "0" > /sys/class/gpio/gpio17/value
    else
    sleep 1  
    fi
    if [ "$pin27" -eq "1" ]
    then
    echo "1" > /sys/class/gpio/gpio27/value
    sleep 1  
    echo "0" > /sys/class/gpio/gpio27/value
    else
    sleep 1  
    fi
    if [ "$pin22" -eq "1" ]
    then
    echo "1" > /sys/class/gpio/gpio22/value
    sleep 1  
    echo "0" > /sys/class/gpio/gpio22/value
    else
    sleep 1  
    fi
    sleep 7
    done
     
  2. Igor68

    Igor68 Гуру

    Пока не понял до конца вашей мысли но... из bash:
    - команда wget - загрузка страницы из http сервера. Если без сохранения в файл, а с выводом в консоль:
    Код (Bash):

    pr=`wget -c http://$IP1 -O -`
     
    после чего в bash остаётся только анализировать строку pr, которая и есть содержимое страницы $IP1... в Вашем случае это локальный адрес локального сервера.

    - применить... ну например telnet... для доступа к странице:
    Код (Bash):

    tinstr0=$((
                    echo -e "$toutstr"
                    sleep 2
            ) | telnet $addr $port)
     
    тут $toutstr это строка запроса вашему серверу(локальному). tinstr0 - это ответ всего диалога. Строка запроса - http запрос по всем правилам. $addr $port - адрес и порт соответственно. Порт указать обязательно - иначе запрос будет по стандартному порту telnet.
    Вообще локально наверное это лишнее. И с затиранием файла каждую секунду поосторожнее... пишете ведь на SD карту... пользуйтесь лучше RAM диском!

    В php на сервере обращайтесь к bash посредством:
    PHP:

    $res = shell_exec($cmd);
     
    $cmd - это команда... допустим имя вашего bash скрипта даже с параметрами, а $res - то, что в консоли отдаст этот самый скрипт. Весь механизм... в комплексе позволит взаимодействовать через сеть двум машинам.

    Локально же удобнее просто применить цикл в bash скрипте локально. Ну допустим:
    Код (Bash):

    !/bin/bash
    ......
    ((loop=1))
    while ( ((loop > 0)) )
     do
       .......
       # тут где-то ваш анализ состояния работы Arduino
       # и управление перезапуском
    done
     
    Сам скрипт запустите с "ключом" & ... например ./arestart & Таким образом с этим ключом ваш скрипт можно поставить в автозапуск ну допустим в /etc/local.rc, только стоит отметить что скрипт при этом будет запущен с правами root. То есть и остановить его работу (kill, killall) можно только с правами root. Сталкивался с аналогичной темой тут:
    http://www.moxa.ru/forum/index.php?/topic/6748-avtozapusk-ot-polzovatelia-v-ia240/

    Простите, если, что лишнее!
     
    Последнее редактирование: 4 мар 2017
    arkadyf и user999 нравится это.
  3. user999

    user999 Гик

    а вот такую команду можно выполнить из php скрипта?
    Что бы вообще bash файл не использовать?
    Код (C++):
    echo "1" > /sys/class/gpio/gpio17/value
     
  4. Igor68

    Igor68 Гуру

    Собственно практически всё рассматривается как файл. Даже /dev/ttyUSB0 например это файл и туда тоже можно через echo передать значения... часто применял подобные конструкции. Но как вы поняли что-то для GPIO должно быть в системе. Тут информация на эту тему:
    http://ph0en1x.net/news/86-raspberry-pi-znakomstvo-s-gpio-perekluchatel-i-svetodiod.html
    Обратите внимание - там в начале для питона, а потом:

    Одним словом bash вполне достаточен и не требуется ни apache+php ни phyton. Но бывает, что требуется как-то через WEB страницу... вот пост выше и описывает эти механизмы.
     
    arkadyf нравится это.
  5. Igor68

    Igor68 Гуру

    Сразу не понял... но эта команда будет выполнена из PHP:
    PHP:
    <?php
        $cmd = "echo "1" > /sys/class/gpio/gpio17/value";
        $res = shell_exec($cmd);
        echo $res;
    ?>
     
    Но следует не забывать, что ваш скрипт должен работать не из среды apache... то есть не при открытии HTML страницы. В противном случае контроль за работой устройств (Arduino) в теневом режиме производится не будет. Впрочем мне попадался сервер какой-то на PHP, который при открытии HTML запускался и работал в тени. Гораздо удобнее запускать контроль при запуске от имени apache. В моём случае пользователь = "www-data", и соответственно рестарт и т.д. возможен только от этого пользователя или "root". Автозапуск phyton видел со скриптами, а php только предполагаю... но наверное можно.
     
    user999 и arkadyf нравится это.
  6. user999

    user999 Гик

    Спасибо большое за развернутые ответы.
    Я планирую написать такой скрипт
    Код (Bash):
    #!/bin/bash
    while true; do
    curl "http://localhost/data.php?action=status"
    sleep 10
    done
    Скрипт каждые 10 сек. будет обращаться к страничке, а та в свою очередь сделает все, что мне нужно, т.е. проанализирует как давно ардуинки были в сети, перезагрузит нужные, отправит мне смс, запишет данные в базу данных
     
  7. user999

    user999 Гик

    У меня еще вопрос. Как php скриптом проще всего определить, что нет доступа к сети?
    Ведь если глюкнул роутер, то его нужно перезагрузить вначале, а потом уже смотреть, как себя чувствуют ардуинки.
     
  8. rkit

    rkit Гуру

    Проще всего заплатить на 300 рублей больше за роутер, который не глюкнет.
    А так тем же курлом из пхп скачивайте какую-нибудь страницу.
     
  9. mcureenab

    mcureenab Гуру

    А что вам от сети надо?
    Доступ к хосту командой ping обычно проверяется. Но упасть может и dns и конечный сервис. Так что надёжнее обрабатывать ошибки взаимодействия с удаленным сервисом, чем гонять тесты.
     
  10. mcureenab

    mcureenab Гуру

    Открыть файл
    /sys/class/gpio/gpio17/value
    , записать в него 1, закрыть файл.
     
  11. user999

    user999 Гик

    Не выполняется команда, наверное что то с правами доступа
     
  12. rkit

    rkit Гуру

    А в логах чего написано* И какие права выставлены?
     
  13. mcureenab

    mcureenab Гуру

    Наверное что то с кавычками.
     
  14. user999

    user999 Гик

    кавычки пробовал разные (", `, ')
     
  15. mcureenab

    mcureenab Гуру

    Это не исключает повторения ошибки.
    PHP:
    $cmd = "echo 1 > /sys/class/gpio/gpio17/value";
    PHP:
    $cmd = "echo "1" > /sys/class/gpio/gpio17/value";
     
  16. rkit

    rkit Гуру

    Вообще, вместо ручного тыканья в /sys/ есть утилита gpio, для которой выставлен suid, а значит проблем с правами нету.
     
  17. Igor68

    Igor68 Гуру

    Простите меня, что забыл... но передаваемые кавычки надо "экранировать":
    PHP:

    $cmd = "echo "1" > /sys/class/gpio/gpio17/value"; //так есть
    $cmd = "echo \"1\" > /sys/class/gpio/gpio17/value"; //так экранировать
     
    Это так же и для BASH скриптов надо... не только для PHP.
    Ещё раз простите!!!

    Возможно ребята имели ввиду не доступ к устройству. Если они зашли от пользователя, сделали скрипт... или скопировали его, а запускают от имени apache на WEB интерфейсе (у меня как пользователь www-data).
     
    arkadyf нравится это.
  18. user999

    user999 Гик

    Если нет прав, то к утилите тоже не получится из PHP обратиться
     
  19. rkit

    rkit Гуру

    А зачем вы их отобрали?
     
  20. user999

    user999 Гик

    Так проходит
    PHP:
    $cmd = 'echo "1" > /sys/class/gpio/gpio17/value';
    $cmd = 'echo 1 > /sys/class/gpio/gpio17/value';
    Но ничего не выводит.
    Как быть с правами, что бы дыру не оставить