php exec bash скрипты: нет такого файла или каталога

#php

#php

Вопрос:

У меня есть несколько сценариев bash и perl, которые было предложено сделать исполняемыми через веб-интерфейс. Ничего особенного, просто для легкого доступа. PHP, казалось, был быстрым и грязным решением для этой цели [через exec() ]. Поэтому я отключил безопасный режим в php.ini и попробовал

 $output = array();
exec('/var/www/vhosts/default/htdocs/scripts/RUN.sh',$OUTPUT);
print_r($output);
var_dump($output);
  

Теперь любые файлы, к которым обращаются в RUN.sh скрипт (доступ к которому осуществляется по относительному пути) не найден. Есть ли какой-либо способ заставить это работать, не указывая полный путь к каждому отдельному перенаправлению (или любому файлу, если на то пошло), к которому обращаются в сценариях?


После применения принятого решения:

Скажем, одна строка из скрипта:

 time python idsplitter.py OUTPUT/TMP/tokens OUTPUT/token_splits
echo "done"
  

В то время time как вывод -s передается в файл error_log, «готово» никогда не передается в массив $OUTPUT . Возвращаемое значение в третьем аргументе exec() при печати на странице дает 0 .


Обновление: time команда отправляет его в stderr, поэтому, если сделать `

 t=`time some_command 2>amp;1`
  

тогда также ничего не сохраняется в t. Так что это имеет смысл. Всем спасибо за помощь…

Комментарии:

1. вы должны установить рабочий каталог для RUN.sh . вы можете использовать chdir до exec или использовать exec cd WORKING_DIRECTORY; ./RUN.sh .

Ответ №1:

Измените текущий рабочий каталог как часть самого скрипта.

Ваш рабочий каталог, с точки зрения RUN.sh скрипта, не то, что вы думаете. Поэтому относительные пути в скрипте не указывают там, где предполагалось.

Чтобы исправить это, вам нужно заставить текущий рабочий каталог быть тем, который работает с относительными путями. Итак, либо:

  • используйте абсолютные пути или
  • измените текущий рабочий каталог с помощью вызова cd [/absolute/path] RUN.sh скрипта, чтобы заставить его быть правильным.

Комментарии:

1. Ааа … эххх.. Я почти на месте … time в RUN.sh чьи выходные данные должны перейти на веб-страницу. Но это так не работает, вывод перенаправляется на /var/log/httpd/error_log . Он продолжает печатать Array ( ) array(0) { } , как будто ничего не произошло!

2. Хм, можете ли вы опубликовать фактический скрипт где-нибудь, чтобы я мог рассмотреть поближе?

3. обновлено исходное сообщение … спасибо за помощь @normalocity

Ответ №2:

Можете ли вы выполнить chdir(2) вызов в вашем PHP-скрипте непосредственно перед exec() вызовом, чтобы получить желаемые результаты? Или это слишком сильно расстроит ваш интерпретатор PHP? (С CGI-скриптами это вообще не было бы проблемой; но FastCGI или подобные механизмы могут вам не понравиться.)

Полагаться на относительные пути уже немного быстро и грязно, и это просто увековечивает его. Возможно, исправление скриптов — лучший подход.

Редактировать

Я застрял в том, что вывод перенаправляется на error_log , а не на страницу php, есть идеи, почему?

Это признак того, что программа отправляет свои выходные данные в стандартную ошибку, а не в стандартный вывод.

Но есть сложность с time — обычно, когда вы запускаете time , вы получаете bash(1) встроенное time ключевое слово reserved . Я не могу найти простой способ попросить bash(1) отправить вывод time зарезервированного ключевого слова в другой файловый дескриптор. Однако вы также можете запустить time(1) программу (которая находится внутри /usr/bin/time ). По умолчанию time(1) вывод переходит в стандартную ошибку, но вы можете перенаправить вывод по своему усмотрению:

 $ /usr/bin/time echo hello
hello
0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext 0avgdata 2528maxresident)k
0inputs 0outputs (0major 206minor)pagefaults 0swaps
$ /usr/bin/time echo hello > /dev/null
0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext 0avgdata 2544maxresident)k
0inputs 0outputs (0major 207minor)pagefaults 0swaps
$ /usr/bin/time echo hello > /dev/null 2amp;>1
$ 
  

Чтобы time(1) результат больше походил на time оболочку, встроенную в вывод ключевых слов, вы можете использовать -p опцию:

 $ /usr/bin/time -p echo hello
hello
real 0.00
user 0.00
sys 0.00
  

Итак, замените строку:

 time python idsplitter.py OUTPUT/TMP/tokens OUTPUT/token_splits
  

с помощью строки:

 /usr/bin/time -p python idsplitter.py OUTPUT/TMP/tokens OUTPUT/token_splits 2>amp;1
  

и вы должны быть готовы к работе.

Комментарии:

1. Я застрял с перенаправлением вывода на error_log, а не на страницу php, есть идеи, почему?