cron job - ack: команда не найдена

У меня есть сценарий bash, который я написал, чтобы определить, существует ли определенная строка в файле или нет, а затем вывести имя файла в «hasString.txt» из «noString.txt». Я использую ack -i 'mystring' 'searchDir', чтобы найти то, что ищу.

Странно то, что когда я вручную вызываю скрипт через терминал, он работает отлично, но когда cron вызывает скрипт, я получаю следующее сообщение об ошибке:

~/sourceDir/script.sh: line 30: ack: command not found.

Почему он работает при вызове вручную, но не может найти команду ack при вызове cron?


редактировать: добавление соответствующего кода и файла cron

Сценарий Lookout — определяет, есть ли какие-либо файлы для обработки.

    if [[ $(ls -A ${PWD}/*.zip) ]]; then
        while [ $different -eq 1 ]; do
            du -h 1> $compare1
            ls -laR >> $compare1 
            sleep 25s
            du -h 1> $compare2
            ls -laR >> $compare2

            if cmp $compare1 $compare2 ; then   
                mkdir -p $LOGAREA
                mkdir -p $workarea/zip/unzip
                touch $LOG
                touch $ERRORLOG
                sleep 2s
                source ~/Desktop/Scripts/readfolderfiles.sh $drop
                mv *epub $workarea
                rm $compare1
                rm $compare2
                bash ~/Desktop/Scripts/Page_Label/script/searchString.sh
                different=0
            else
                echo
            fi
        done 1> $LOG 2> $ERRORLOG
    else
    rm ~/Desktop/page_labels.running
    rm $drop/page_labels.running
    fi 

Определить сценарий и сообщить о нем — генерирует выходные данные, упомянутые выше.

for files in *.zip; do
    #move and unzip the files
    mv $workarea/$files $workarea/zip/unzip/${files%.epub}.zip
    sleep 2s
    unzip zip/unzip/*.zip -d zip/unzip/${files%.epub}
    mv zip/unzip/*.zip zip
    sleep 2s
    cd $workarea/zip/unzip
    for dir in *; do
        # Search the files for the searchString
        if ack --ignore-case 'searchString' $dir; then
            echo $dir >> $drop/Has_searchString.txt
            echo
            rm -r $dir
            sleep 5s
        else
            echo $dir >> $drop/No_searchString.txt
            echo
            rm -r $dir
            sleep 5s
        fi
    done
    cd $workarea
done

Крон документ

#!/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

#### Backup Files
* * * * 1,2,3,4,5 bash  ~/Desktop/Scripts/searchScript.sh &> /dev/null;

person I Dabble    schedule 27.10.2014    source источник
comment
Окружение cron весьма ограничено и путь ack может быть ему неизвестен. Таким образом, вы можете добавить полный путь в свой скрипт (/bin/ack -i 'mystring' 'searchDir' или что-то еще, что вы получите от which ack).   -  person fedorqui 'SO stop harming'    schedule 27.10.2014
comment
@fedorqui Я пробовал. Нет игральных костей. Все еще работает только при вызове вручную   -  person I Dabble    schedule 27.10.2014
comment
ОК, затем опубликуйте соответствующие части вашего кода вместе с синтаксисом cronjob.   -  person fedorqui 'SO stop harming'    schedule 27.10.2014
comment
Проблема (или по крайней мере одна из них) заключается в том, что вы используете ~ для работы с домашним каталогом. Crontab этого не знает, поэтому вместо этого вам нужно использовать полный путь.   -  person fedorqui 'SO stop harming'    schedule 27.10.2014
comment
@fedorqui Я попробую, но у него нет проблем с вызовом скрипта. Он просто не может найти подтверждение, когда вызывается из скрипта (примерно на полпути во втором блоке кода)   -  person I Dabble    schedule 27.10.2014
comment
Где на самом деле установлен ack? which ack может вам сказать. Если он показывает каталог, который находится в PATH, который вы установили в файле crontab, это озадачивает — на это будет причина, но мы еще не нашли ее. Если он показывает каталог, которого нет в указанном вами ПУТИ, есть ответ. Вы повторно отправили crontab после внесения изменений в файл?   -  person Jonathan Leffler    schedule 28.10.2014
comment
Ответ @JonathanLeffler находится в /usr/local/bin/ack. Единственное, что изменилось в моем cron на данный момент, это то, что я заменил жесткий путь вместо ярлыка ~.   -  person I Dabble    schedule 28.10.2014
comment
Строка mv $workarea/$files, вероятно, не делает ничего полезного; mv требует два аргумента, а вы, кажется, даете только один. Вы должны запустить свой сценарий так, чтобы выходные данные попадали в файл журнала, а не в /dev/null; это позволит вам легче увидеть, что происходит не так. Вы также должны изменить сценарий, чтобы он распечатывал его среду (временно), чтобы вы могли видеть фактическое значение PATH, когда сценарий запускается cron. Являются ли какие-либо другие программы, которые вы используете в этих сценариях, также в /usr/local/bin? Ваш основной скрипт пишет в $ERRORLOG. Есть ли там полезная информация?   -  person Jonathan Leffler    schedule 28.10.2014
comment
Вместе с очень полезным указанием от Джонатана Леффлера я бы еще сказал: цитата. mv "$workarea/$files" "something_else". Таким образом, вы предотвратите проблемы, если имена файлов содержат пробелы или другие сложные символы.   -  person fedorqui 'SO stop harming'    schedule 29.10.2014
comment
@JonathanLeffler Плохо. Я как-то пропустил копирование места назначения. Обещаю, это было в моем сценарии. Я добавил это выше. @fedorqui В именах файлов никогда не будет пробелов. Система, в которой они хранятся, не допускает пробелов. Поскольку у нас так много проблем с ack, полагаю, мне следует спросить, могу ли я сделать то же самое с grep. Мне не удалось заставить grep делать то же, что и ack, описанное выше, но, возможно, кто-то другой лучше меня разбирается в grep.   -  person I Dabble    schedule 29.10.2014


Ответы (2)


Вам нужно установить переменную среды PATH в вашем задании cron. Итак, добавьте это в начало файла cron:

 #!/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

Примечание: также добавьте #!/bin/bash, поэтому вам не нужно также добавлять переменную среды оболочки.

person eax_rabb1t    schedule 27.10.2014
comment
Да, мой плохой. Спасибо :) - person eax_rabb1t; 27.10.2014
comment
Я попытался добавить это в свои настройки cron, но не в кости. #!/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin * * * * * bash ~/script &> /dev/null; - person I Dabble; 27.10.2014

Это потому, что путь поиска не определен.

Используйте либо полный путь в своем скрипте, либо определите путь

Опция 1:

/path/to/ack -i 'mystring' 'searchdir'

Вариант 2:

PATH=/path/to/ackdir:$PATH
export PATH

ack -i 'mystring' 'searchdir'
person Arunas V.    schedule 27.10.2014
comment
Я попытался добавить полный путь к ack в оболочке /usr/local/bin/ack, но это все равно не сработало. Я также попытался добавить вариант 2 в свой файл cron, но и там не повезло. - person I Dabble; 27.10.2014
comment
Глядя на скрипт и cronjob, которые вы указали в своем вопросе. Пожалуйста, убедитесь, что вы избегаете использования домашнего ярлыка ~/ это потому, что вы можете написать скрипт в домашней папке вашего пользователя, которая находится в /home/user, но cronjobs запускаются под пользователем root, поэтому значение ~/ в этом случае будет другим. Если только вы не определите cronjob под тем же пользователем. - person Arunas V.; 28.10.2014
comment
Вчера я удалил ярлык ~ и заменил его жесткими путями. Не изменил результат. - person I Dabble; 28.10.2014
comment
@ArunasV.: Нет, задание cron выполняется под пользователем, который выполнил команду crontab для его установки. Запуск заданий cron от имени пользователя root был бы ужасной дырой в безопасности. - person Keith Thompson; 28.10.2014