n.b. большая часть этого ответа имела гораздо больше смысла до редактирования вопроса :)
Ошибка проста:
if [ "$1" == "proto" ]; then
TESTVAR=
if [ "$1" == "set" ]; then
HISTFILE=$2
HISTFILESIZE=$3
elif [ "$1" == "incognito" ]; then
# ....
Второй if
здесь должен быть elif
. bash
жалуется, потому что не может найти подходящий fi
.
Есть еще две вещи, которые я хотел бы упомянуть о скрипте:
Он будет запущен в подпрограмме и выполнит вывод команды unset
, что не то, что вы хотите:
$(unset HISTFILE)
Вы должны удалить из него оператор $(...)
.
Оператор #!/bin/bash
подразумевает, что скрипт исполняется отдельно, как аргумент к бинарному файлу /bin/bash
. Это не имеет смысла для такого сценария, поэтому я бы не советовал этого делать (и я бы не советовал устанавливать на него разрешение исполняемости).
И последнее. Разбор аргументов с помощью вложенных if/else - немного неудобный способ. Вы можете использовать оператор case
:
case $1 in
(proto) TESTVAR= ;;
(set)
HISTFILE=$2
HISTFILESIZE=$3
;;
#...etc...
("")
# ... put your usage here...
;;
(*)
echo >&2 "ERROR: Option unrecognized"
echo >&2
echo >&2 "run . ./history.bash for help"
;;
esac
Заставить скрипт работать под zsh:
==
на =
. Оператор ==
является нестандартным псевдонимом оператора =
, и это один из случаев, когда он ломается. HISTFILESIZE
в SAVEHIST
У меня были похожие проблемы с cron
заданиями. Я не могу конкретно сказать, что не так с вашей записью cron
, но я поделюсь некоторыми мыслями о том, что я заметил о различиях между cron
запуском сценария и интерактивной оболочкой, выполняющей сценарий.
Во-первых, cron
НЕ читает вашу локальную среду, по умолчанию PATH
, я полагаю, /usr/bin:/usr/sbin
. Один из тестов, который можно попробовать, — это распечатать переменные среды в начале сценария и запустить их в интерактивном режиме, а затем запустить из cron и увидеть разницу.
#!/bin/bash
env
Во-вторых, не думайте, что вы работаете из своего домашнего каталога. Укажите ВСЕ пути. то есть /bin/date
, /home/pi/scriptname.sh /home/pi/filename
и т. д.
В-третьих, попробуйте указать в скрипте вашу локальную среду и/или попробуйте добавить опцию -f
в ваш shebang
#!/bin/bash
. /home/pi/.bashrc #Not the period space at the beginning of the line
или
#!/bin/bash -f
В-четвертых, проверьте вывод журнала сценария, чтобы убедиться, что он обрабатывает правильные файлы и действительно устанавливает ваши переменные. Вы можете сделать это, прочитав журнал cron
(везде, где у вас установлено значение журнала ), или перенаправить STDIN и STDOUT в файл:
0 1,7,13,19 * * * /home/pi/Dropbox-Uploader/processByDate.sh /home/pi/camfiles.txt 2 >/dev/null 2>&1
Проблема в том, что цикл while -реализован в подоболочке. Вот объявление , в котором обсуждается это и возможное правильное решение.
Но я был настолько разочарован этой проблемой, что стараюсь вообще ее избегать. Использование файла для хранения переменных не принесет вам очков за элегантность, но это работает. Этот небольшой сценарий иллюстрирует это.
#!/bin/bash
c=0
FILE=/tmp/$(basename $0).$$
while IFS= read -r line; do
((c++))
echo "count=$c" > $FILE
done < somefile
. $FILE
echo "Read $count lines"
rm -f $FILE