Сделайте это в VirtualBox. Просто установите Live CD iso в качестве загрузочного устройства и загрузите машину. У вас не должно возникнуть проблем.
Вероятно , потому что вы запускаете команды в конвейере.
Каждая часть конвейера запускается в одно и то же время и выполняется одновременно с другими частями того же конвейера. Это означает, что команда find
запускается точно в то же время, что и команда sed
. Только данные, проходящие через конвейер, из стандартного вывода одной команды в стандартный ввод следующей, синхронизируют различные команды.
Также обратите внимание, что на самом деле вы не используете аспект конвейера. Данные между командами не передаются.
Ваш сценарий лучше написать как
#!/bin/bash
#Creates index file.
find /var/www/html/uploads/Music/ -name '*.mp3' > /var/www/html/uploads/Music/songs.index
sed -i -e 's/\/var\/www\/html/\.\./g' /var/www/html/uploads/Music/songs.index
Здесь команда find
завершает выполнение до начала команды sed
. Я также удалил команду sudo
так как она явно не нужна (если find
может писать в файл, то sed
может читать и изменять его безsudo
).
Если вы обнаружите, что вам действительно нужно sudo
для записи songs.index
, я бы посоветовал вам вместо этого запустить это задание cron в crontab, принадлежащем пользователю с разрешениями на запись в целевой каталог. /var/www/html/uploads/Music
.
Конвейерным решением будет
#!/bin/sh
#Creates index file.
find /var/www/html/uploads/Music/ -name '*.mp3' |
sed -e 's,^/var/www/html,..,' >/var/www/html/uploads/Music/songs.index
Здесь find
записывает непосредственно в команду sed
, а результат команды sed
записывается в индексный файл. Передача данных (путей )из find
в sed
поддерживает синхронизацию двух процессов, и sed
будет ждать для find
создания следующей строки ввода, прежде чем продолжить (и наоборот; find
будет ждать, пока sed
обработает данные, прежде чем пытаться вывести больше данных ).
Я также упростил чтение команды sed
, привязал регулярное выражение к началу строки и удалил ненужный флаг g
в конце. Поскольку теперь он считывается из команды find
,Я также удалил параметр -i
(, строго говоря, параметр -e
также можно было бы удалить ).
Еще я изменил строку #!
. Вы не используете никакихbash
-специфических функций, поэтому мы можем запустить скрипт с (возможно )более легкой -оболочкой.
Если вы хотите записать имена найденных файлов в индекс, заменив начальный /var/www/html
на ..
, вы также можете сделать это непосредственно изfind
:
#!/bin/sh
#Creates index file.
find /var/www/html/uploads/Music/ -type f -name '*.mp3' -exec sh -c '
for pathname do
printf "../%s\n" "${pathname#/var/www/html/}"
done' sh {} + >/var/www/html/uploads/Music/songs.index
Эта единственная команда find
найдет пути ко всем обычным файлам (, т. е. не к каталогам и т. д. ), чьи имена соответствуют заданному шаблону. Для пакетов этих путей вызывается короткий встроенный сценарий оболочки. Сценарий просто перебирает текущую группу путей и выводит их с небольшими изменениями.
Модификация имени пути выполняется посредством подстановки параметра ${pathname#/var/www/html/}
. Это удаляет строку /var/www/html/
из начала значения в $pathname
. Используемая строка формата printf
гарантирует, что эта часть будет заменена на ../
.
См. также