#bash #unix
#bash #unix
Вопрос:
Я пытаюсь скомпилировать большой проект, который включает в себя переход в разные каталоги и компиляцию там. У меня есть три массива, все они содержат команды, первый массив содержит обход каталога, второй массив содержит команды компиляции, а третий массив содержит сообщения об ошибках.
Я настроил свои массивы следующим образом
task[0]="cd vssl/make/; make clean;"
compile[0]="make all"
error[0]="echo "We failed at vssl install""
task[1]="cd ../../web/make/; make clean;"
compile[1]="make install"
error[1]="echo "We failed at web install""
Теперь мне нужен цикл for, который будет работать следующим образом
for i in {0..$size_of_array}
do
eval ${task[$i]}
if (eval ${compile[$i]}); then
echo "Done"
else
eval ${error[$i]}
break
fi
done
Я много чего перепробовал и не уверен, как этого добиться. for i in "${task[@]}"
у меня тоже не работает, потому что у меня есть три переменные. У кого-нибудь есть представление о том, как это обойти?
Спасибо всем, кто может помочь. 🙂
Ответ №1:
Размер task
массива ${#task[@]}
(прекрасный синтаксис, не так ли?). Таким образом, вы можете начать свой цикл как
for ((i=0; i<${#task[@]}; i))
Смотрите for
команду и раздел об АРИФМЕТИЧЕСКОМ ВЫЧИСЛЕНИИ в bash(1) для получения подробной информации.
Комментарии:
1. Большое вам спасибо, это именно то, что я хотел!!! Тоже отлично работает. Спасибо!
2. Отличная идея! Все это объясняется в разделе «Расширение параметров» bash(1).
Ответ №2:
Вы можете вычислять $i
по ходу работы:
i=0
for cmd in "${task[@]}"; do
eval $cmd
if (eval ${compile[$i]}); then
echo "Done"
else
eval ${error[$i]}
break
fi
i=`expr $i 1`
done
Комментарии:
1. Я боялся, что вы скажете это, потому что я хотел, чтобы красивый цикл for делал мои вещи за меня. Но большое вам спасибо, это сработало довольно хорошо.
2. Ответ @AndrewSchulman тоже выглядит хорошо; Признаюсь, я не знал, что вы могли бы написать for-циклы, подобные тем, что в bash.
Ответ №3:
Почему в мире у вас есть три массива? Оболочка не так хороша для программирования, но она отлично подходит для выполнения команд, что вы, похоже, и делаете здесь. Итак, просто сделайте это:
set -ex
make -C vssl/make clean all
make -C ../../web/make/ clean install
...
Недостаточно причудливо? ОК:
die() { echo "$*" >amp;2; exit 1; }
run() { "$@" || die "Failed (exit $?) at $*"; }
run make -C vssl/make clean all
run make -C ../../web/make/ clean install