LinuxForum.Fans
Тема

Ошибка в команде

Автор: swordholder 22 сообщений 4551 просмотров
#92395

Здравствуйте, я не Линуксоид по этому прошу страшно не ругать за вопрос.

У меня в папке /var/spool/asterisk/monitor/ есть куча .wav файлов (Система Астериск генерирует)

Я хотел написать скрипт чтоб превращать .wav файлы в .mp3 файлы (так как они занимают меньше место на диске) и перекинуть в отдельную папку создаваемую этим же скриптом (файл можно назвать сегоднячней датой)
Допустим если я сегодня запущу скрипт то .wav файлы должны превратиться в .mp3 и перекинуться в папку /var/spool/asterisk/monitor/2008-10-27/ (.wav файлы потом сразу же можно удалять)

В гугле ничего интересного по теме не нашел по этому решил обратиться к вам.

Откуда то откапал баш скрипт (т.к. сам не владею знаниями написания баш скриптов) но есть ошибки, уважаемые линуксоиды пожалуйста помогите чем сможете.

Вот мой карявый скрипт

text

#Конвертируем .wav файлы в .mp3, перекидываем в новую папку если папка с названием сегоднячней даты существует просто туда копируем

work_dir="/var/spool/asterisk/monitor" for i in `ls $work_dir/*.wav`; do cd $work_dir $work_dir/mlame -f -o "-b 16 -m m -q 9 --resample 8" $i date=`ls -l $i | awk '{print $6}'` mp3=`echo $i | sed 's/.wav/.mp3/g'`

#удаляем уже ненужные файлы .wav work_dir=/var/spool/asterisk/monitor cd $work_dir rm $work_dir/*.wav

Скриншот ошибки:


Версия ОС:

#92405

Попробуйте вот такой скриптик:

text

#!/bin/bash

WORK_PATH="/var/spool/asterisk/monitor"

cd $WORK_PATH find . -iname "*.wav" -exec lame '-b 16 -q 0' '{}' ';' mkdir `(date +%Y-%m-%d)` mv *.mp3 `(date +%Y-%m-%d)` rm *.wav

Для этого просто в текстовом редакторе создайте файл, к примеру
[console]nano wav_to_mp3[/console]
скопируйте туда текст скрипта, и выдайте права на исполнение
[console]chmod +x wav_to_mp3[/console]
После просто запустите ./wav_to_mp3

Ах да, для работы скрипта, должен быть установлен пакет lame.
[console]aptitude install lame[/console]

#92426

Ваш скрипт по моему удаляет если папка (date +%Y-%m-%d) уже существует так ?
А я могу в день по 10-20 раз запускать скрипт допустим могу запланировать (на cron'е)
и нехотелось бы чтоб каждый раз файлы внутри папки (date +%Y-%m-%d) удалялись.

Что скажете ?

#92469

В этом скрипте удаляются .wav файлы внутри WORD_PATH, а .mp3 файлы только перемещаются из WORD_PATH в WORD_PATH/<текущая дата>. С содержимым папки <текущая дата> ничего не делается, кроме добавления новых файлов. Можно конечно прикрутить проверку "Существует ли уже данная папка", но без этой проверки, Вы максимум увидите сообщение вида "mkdir: невозможно создать каталог «27-10-2010»: Файл существует". Скрипт продолжит работу не создавая новой папки, и соответственно содержимое папки <Текущая дата> не изменится, после чего в нее будут перемещены новые файлы(если они будут). если будет мешать сообщение о невозможности созтать папку, просто перенаправте вывод на /dev/null, привидя строку к виду


mkdir `(date +%Y-%m-%d)` > /dev/null
#92503

Большое вам человеческое спасибо EdmunDD

К этой задаче добавилось еще одна задача. (Вернее в первом посту я забыл о нем)
Я вас конечно замучал но это последнее.

После изменения пути файла мне еще нужно будет изменить данные в базе MySQL. (То есть так же изменить путь файла в таблице)
Следовательно к вашему скрипту нужно еще один момент прикрутить. (SQL запросчик в локальную базу)

То есть допустим есть у меня 3 файла в папке /var/spool/asterisk/monitor/
1. file1.wav
2. file2.wav
3. file3.wav

Дело в том что имена файлов в таблице храняться без расширения. Значит мы должны написать запрос следующего вида:

text

#до этой точки мы уже сконвертировали все .wav файлы в .mp3 и скинули в новую папку с названием сегоднячней даты.

UPDATE my_table SET file_path = '[НАЗВАНИЕ_СОЗДАННОЙ_ПАПКИ]' WHERE file_name IN ('file1','file2','file3');

НАЗВАНИЕ_СОЗДАННОЙ_ПАПКИ это сегоднячняя дата например '2010-10-27'

Заметьте в запросе имена файлов оказались без расширения.
Как это можно реализовать ?
Имена файлов (без расширения) сначало можно собрать в одну переменную в цикле foreach и добавив между ними запятые и потом вставить в запрос.
На PHP или на C# я бы запросто сделал бы такое но только ни в командной строке линукса.

wink

#92512
swordholder написал:
На PHP или на C#  я бы запросто сделал бы такое но только ни в командной строке линукса

Вам никто и не запрещает использовать к примеру PHP в линуксе. Достаточно лишь установить интерпретатор:
[console]aptitude install php5-cli[/console]
И запускать скрипт из консоли командой php
[console]php <имя скрипта php>[/console]
А получить в PHP список файлов в каталоге лехко:

text

<?php
  exec('ls /var/spool/asterisk/monitor/'.date('Y-m-d'),$file_list);
?>

В результате чего Вы получите обычный массив $file_list, который содержит имена файлов.

#92532
swordholder написал:
На PHP или на C# я бы запросто сделал бы такое но только ни в командной строке линукса.

ну и напишите. а мы переведём ;)

откусить "расширение":
[console]doc@bx:~$ F="test.wav"
doc@bx:~$ echo $F
test.wav
doc@bx:~$ echo ${F%.wav}
test
[/console]

в консоли удобнее работать с файлами-списками. Получить список можно либо так:
[console]/bin/ls >file-list.txt[/console]
либо так:
[console]find . > file-list.txt[/console]
обработать такой список можно в цикле:

text
while read FILE_NAME
do
# тело цикла
# используем $FILE_NAME
done < file-list.txt
#92534
drBatty написал:
обработать такой список можно в цикле:

Или так:

text

for i in $(ls -1);
do
# тело цикла, к примеру
echo $i
done
#92546
EdmunDD написал:
[quote=swordholder]На PHP или на C#  я бы запросто сделал бы такое но только ни в командной строке линукса

Вам никто и не запрещает использовать к примеру PHP в линуксе. Достаточно лишь установить интерпретатор:
[/quote]

Я уже написал скрипт на ПХП все дело в том что вручную мой скрипт работает хорошо только не могу добавить в планировщик (cron). Вернее добавить название скрипта не проблема а вот почему то не запускается. То ли запускается но где то что то каряво стоит по этому не пашет скрипт по расписанию.
И по этому подумал может командами линукса управиться. Может я не прав.

Вот скриншот



А вот мой ПХП код. Которого запускаю на командной строке и работает без ошибок.

text

#!/usr/bin/php -q
<?php

$db='asterisk'; $user='asterisk'; $password='yourpassword'; $host='localhost'; $cdr_path="/var/spool/asterisk/monitor"; $freshFolder=date("Y-m-d");

//executing bash file to converto all *.wav files to *mp3 //system("/bin/sh tomp3.sh");

//files are converted lets now copy them to a folder

$dhandle = opendir($cdr_path); // define an array to hold the files $files = array();

if ($dhandle) { // loop through all of the files while (false !== ($fname = readdir($dhandle))) { // if the file is not this file, and it's not a directory, and it has .mp3 extension and does not start with a '.' or '..', // then store it for later display if (($fname != '.') && ($fname != '..') && ($fname != basename($_SERVER['PHP_SELF'])) && !is_dir($fname) && getFileExt($fname)=="mp3") $files[] = $fname; echo "Processing file: ".$fname."\n"; }//end while // close the directory closedir($dhandle); } chmod($cdr_path,0777); if(!is_dir($cdr_path."/".$freshFolder)) //create new dir if does not exist { mkdir($cdr_path."/".$freshFolder); chmod($cdr_path."/".$freshFolder,0777); }

// Now loop through the files and move them foreach( $files as $fname ) { echo "Moving file: ".$fname."\n"; rename($cdr_path."/".$fname,$cdr_path."/".$freshFolder."/".$fname); }

//now let's update our DB if(!mysql_connect($host,$user,$password)) { echo "Could not connect to host: ".$host."\n"; exit(); } if(!mysql_select_db($db)) { echo "Could not select db: "; exit(); }

$query="UPDATE cdr SET path_file='".$freshFolder."' WHERE uniqueid IN (".GetInned($files).")"; echo "Executing query: ".$query."\n"; mysql_query($query); mysql_close();

function getFileExt($filename) { return end(explode('.', $filename)); }

function getFilenameWithoutExt($filename) { $pos = strripos($filename, '.'); if($pos === false) { return $filename; }else { return substr($filename, 0, $pos); } }

function GetInned($files)//convert array to sql friendly IN statement { $i=1; $retVal=""; foreach ($files as $file) { //echo $file."<br>"; if($i<sizeof($files)) $retVal.="'".getFilenameWithoutExt($file)."',"; else $retVal.="'".getFilenameWithoutExt($file)."'"; $i++; } return $retVal; }

?>

А вот результат phpinfo():
phpinfo.htm

Пожалуйста помогите мне написать скрипт для решения этой задачи. Или пните в нужном направлении.
Буду очень благодарен.

#92559
Lupo Alberto написал:
for i in $(ls -1); do # тело цикла, к примеру echo $i done

или так:
[console]find . -maxdepth 1 -exec echo '{}' \;[/console]
вариант с файлом-списком имеет много плюсов.

swordholder написал:
Вернее добавить название скрипта не проблема а вот почему то не запускается. То ли запускается но где то что то каряво стоит по этому не пашет скрипт по расписанию.
И по этому подумал может командами линукса управиться. Может я не прав.

не поможет.
по поводу планировщика: вы работаете в неком окружении, т.е. у вас есть набор переменных. А вот в cron'е их нет.
отправьте вывод скрипта в лог-файл, что-бы понять, что происходит. Внутри cron'а даже простейшие команды не работают - нету $PATH, shell попросту не может найти эти команды.

swordholder написал:
А вот мой ПХП код. Которого запускаю на командной строке и работает без ошибок.

и в cron'е заработает.

Хотя на sh будет проще в разы.

#92586
swordholder написал:
Я уже написал скрипт на ПХП все дело в том что вручную мой скрипт работает хорошо только не могу добавить в планировщик (cron). Вернее добавить название скрипта не проблема а вот почему то не запускается. То ли запускается но где то что то каряво стоит по этому не пашет скрипт по расписанию.
И по этому подумал может командами линукса управиться. Может я не прав.

Как уже сказал выше drBatty, cron не знает переменных окружения, потому путь до сценария php надо прописывать польностью.
Обычно это
[console]
/usr/bin/php <скрипт пхп>
[/console]

т.е. строка в crontab'е должна выглядеть примерно так:
0-59 * * * * root /usr/bin/php MoveFiles.php

#92594
EdmunDD написал:
т.е. строка в crontab'е должна выглядеть примерно так:

вообще-то, для редактирования этой строчки надо использовать
[console]crontab -e[/console]

#92614
drBatty написал:
вообще-то, для редактирования этой строчки надо использовать

ну я вообще то имел ввиду конечный результат, а не процесс редактирования :rolleyes:

#92829
EdmunDD написал:
т.е. строка в crontab'е должна выглядеть примерно так:
0-59 * * * * root /usr/bin/php MoveFiles.php

Сделал точно так же все еще не работает.



Так что мои приключения в мире Линукс продолжаются. oO
Какие нибудь еще предложения господа ? :(

#92870
swordholder написал:
Сделал точно так же все еще не работает.

http://img818.imageshack.us/img818/5818/cront.th.jpg

Так что мои приключения в мире Линукс продолжаются. blink
Какие нибудь еще предложения господа ? sad

я не вижу вашей картинки. можно текстом?

и смените строчку
на

text
* * * * * /usr/bin/php MoveFiles.php >> /var/log/mf.log

зайдите под рутом, наберите
[console]crontab -e[/console]
и введите мою строчку.
Важно: текст должен кончатся пустой строкой.
Через пару минут ознакомтесь с содержимым /var/log/mf.log

Совет: откройте ещё один терминал, зайдите там рутом, и наберите
[console]tail -f /var/log/mf.log[/console]
Это позволит вам контролировать процесс в реальном времени.

ЗЫЖ

EdmunDD написал:
ну я вообще то имел ввиду конечный результат, а не процесс редактирования rolleyes

это называется "через *опу".
Пароли вы тоже меняете редактируя /etc/shadow ? А что так?

#93017

drBatty - вы гений.
Я сделал все как вы сказали и пока я тут сижу затаив дыхание и со святой водой в руках время от времени брызгая ею в монитор компьютера все работает. Не знаю что случиться когда я уйду.
oO

Спасибо всем но вопрос не закрыт. Какие еще приключения меня ждут ни одному cronе'у не известно. wink

#93042

Если я уберу с команды крон вот эту часть ">> /var/log/mf.log" мой скрипт все еще будет работать ?

То есть конечный вид будет таким
[console]* * * * * /usr/bin/php MoveFiles.php[/console]

#93088
swordholder написал:
Если я уберу с команды крон вот эту часть ">> /var/log/mf.log" мой скрипт все еще будет работать ?

да. только в лог ничего не будет писаться.

#93089

а случится может вот что:
в 12:34 запустится скрипт и начнёт работу.
в 12:35 запустится копия скрипта и тоже начнёт работу.

Что будет, если 2 копии будут работать одновременно? Обычно - ничего хорошего :(

Стандартное решение: создать файл, в который записать номер процесса. например /var/run/mf.pid
Перед стартом скрипт должен проверить, есть-ли такой файл. И если есть, есть-ли процесс (номер в файле). Если есть и файл и процесс есть - значит это копия, которй надо тихо сдохнуть.

#93130

Спасибо всем вопрос закрыт

Войдите или зарегистрируйтесь, чтобы ответить.