Разделы сайта
Выбор редакции:
- Как программно открыть внешнюю обработку?
- Путеводитель по системам для создания инсталляторов
- ESET NOD32 Antivirus скачать бесплатно русская версия
- Picmonkey — быстрый онлайн фоторедактор Frames
- Как построить график в Маткаде (Mathcad)?
- Рейтинг: «Лучший конструктор лендингов Платформа lp конструктор для создания лендингов
- Собрал файл сервер для 1с
- Обработка для выгрузки справочников из 1с 8
- Система компоновки данных - практика разработкиСКД Консоль - изучение Системы Компоновки Данных OnLine
- История почты и почтовых марок чили Какие бывают трек номера Почты Чили
Реклама
Bash while бесконечный цикл. Бесконечный цикл while в BASH-скрипте |
Автор: Paul Cobbaut Дата публикации: 16 октября 2014 г. Перевод: А.Панин Дата перевода: 21 декабря 2014 г. Глава 22. Циклы в сценарияхКоманда testКоманда test позволяет установить, является ли какое-либо выражение истинным или ложным. Давайте начнем с проверки, больше ли целочисленное значение 10 целочисленного значения 55. $ test 10 -gt 55 ; echo $? 1 $ Команда test возвращает значение 1, если выражение является ложным. И, как вы увидите в следующем примере, команда test будет возвращать значение 0, если выражение будет являться истинным. $ test 56 -gt 55 ; echo $? 0 $ Если же вам удобнее работать со строками true (истина) и false (ложь), вы можете использовать команду test таким образом, как показано ниже. $ test 56 -gt 55 && echo true || echo false true $ test 6 -gt 55 && echo true || echo false false Команда test также может заменяться квадратными скобками, поэтому команды из примера ниже полностью аналогичны командам из примера выше. $ [ 56 -gt 55 ] && echo true || echo false true $ [ 6 -gt 55 ] && echo true || echo false false Ниже приведены примеры реализаций некоторых проверок. Обратитесь к странице руководства man test для ознакомления с дополнительными возможностями реализации различных проверок. [ -d foo ] Существует ли директория foo ? [ -e bar ] Существует ли файл bar ? [ "/etc" = $PWD ] Эквивалентна ли строка /etc значению переменной $PWD ? [ $1 != "secret" ] Отличается ли значение первого параметра сценария от строки secret ? [ 55 -lt $bar ] Меньше ли целочисленное значение 55 значения переменной $bar ? [ $foo -ge 1000 ] Является ли значение переменной $foo большим или равным целочисленному значению 1000 ? [ "abc" < $bar ] Будет ли строка abc расположена выше значения переменной $bar в списке после сортировки? [ -f foo ] Является ли foo обычным файлом? [ -r bar ] Является ли bar читаемым файлом? [ foo -nt bar ] Новее ли файл foo файла bar ? [ -o nounset ] Активирован ли параметр командной оболочки nounset ? Операторы проверок могут комбинироваться с операторами, соответствующими логическим операциям "И" и "ИЛИ". paul@RHEL4b:~$ [ 66 -gt 55 -a 66 -lt 500 ] && echo true || echo false true paul@RHEL4b:~$ [ 66 -gt 55 -a 660 -lt 500 ] && echo true || echo false false paul@RHEL4b:~$ [ 66 -gt 55 -o 660 -lt 500 ] && echo true || echo false true Условный переход if then elseКонструкция if then else предназначена для выбора варианта кода. В том случае, если определенное условие выполняется, будет исполняться какой либо код, в противном случае будет исполняться какой-либо другой код. В примере ниже осуществляется проверка существования файла, после чего в том случае, если предположение о существовании файла подтверждается, осуществляется вывод соответствующего сообщения. #!/bin/bash if [ -f isit.txt ] then echo файл isit.txt существует! else echo файл isit.txt не найден! fi В том случае, если мы сохраним данный код сценария в файле с именем "choice", он сможет быть исполнен аналогичным образом. $ ./choice файл isit.txt не найден! $ touch isit.txt $ ./choice файл isit.txt существует! $ Условный переход if then elifВы можете разместить новый оператор условного перехода if внутри блока else , воспользовавшись оператором elif . Ниже приведен простой пример такой записи. #!/bin/bash count=42 if [ $count -eq 42 ] then echo "42 является корректным значением." elif [ $count -gt 42 ] then echo "Слишком много." else echo "Не достаточно." fi Цикл forВ примере ниже представлен синтаксис классического цикла for в командной оболочке bash. for i in 1 2 4 do echo $i done Пример использования цикла for , скомбинированного с вызовом встраиваемой командной оболочки. #!/bin/ksh for counter in `seq 1 20` do echo отсчет от 1 до 20, текущее значение $counter sleep 1 done Сценарий, полностью аналогичный представленному выше, может быть создан и без задействования встраиваемой командной оболочки путем использования реализованного в рамках командной оболочки bash объявления диапазона значений {от значения..до значения} . #!/bin/bash for counter in {1..20} do echo отсчет от 1 до 20, текущее значение $counter sleep 1 done В данном цикле for используется механизм поиска файлов по шаблону (реализованный в рамках механизма раскрытия команд). В случае размещения приведенной инструкции непосредственно в командной строке, она будет функционировать аналогично. kahlan@solexp11$ ls count.ksh go.ksh kahlan@solexp11$ for file in *.ksh ; do cp $file $file.backup ; done kahlan@solexp11$ ls count.ksh count.ksh.backup go.ksh go.ksh.backup Цикл whileНиже приведен простой пример использования цикла while . i=100; while [ $i -ge 0 ] ; do echo Обратный отсчет от 100 до 0, текущее значение $i; let i--; done Бесконечные циклы могут реализовываться с помощью объявлений while true или while: , где символ: является эквивалентом отсутствующей операции в командных оболочках Korn shell и bash . #!/bin/ksh # бесконечный цикл while: do echo hello sleep 1 done Цикл untilНиже приведен простой пример использования цикла until . let i=100; until [ $i -le 0 ] ; do echo Обратный отсчет от 100 до 1, текущее значение $i; let i--; done Практическое задание: проверки и циклы в сценариях3. Разработайте сценарий, который будет использовать цикл while для отсчета от 3 до 7. 4. Разработайте сценарий, который будет использовать цикл until для обратного отсчета от 8 до 4. 5. Разработайте сценарий, который будет производить подсчет файлов с расширением.txt в текущей директории. 6. Используйте оператор if в созданном сценарии для его корректной работы в случае отсутствия файлов с расширением.txt в текущей директории. Корректная процедура выполнения практического задания: проверки и циклы в сценариях1. Разработайте сценарий, который будет использовать цикл for для отсчета от 3 до 7. #!/bin/bash for i in 3 4 5 6 7 do echo Отсчет от 3 до 7, текущее значение $i done 2. Разработайте сценарий, который будет использовать цикл for для отсчета от 1 до 17000. Оболочка bash поддерживает циклы for , которые позволяют организовывать перебор последовательностей значений. Вот какова базовая структура таких циклов:For var in list
do
команды
done
Перебор простых значенийПожалуй, самый простой пример цикла for в bash-скриптах - это перебор списка простых значений: #!/bin/bash
for var in first second third fourth fifth
do
echo The $var item
done
Обратите внимание на то, что переменная $var сохраняет значение при выходе из цикла, её содержимое можно менять, в целом, работать с ней можно как с любой другой переменной. Перебор сложных значенийВ списке, использованном при инициализации цикла for , могут содержаться не только простые строки, состоящие из одного слова, но и целые фразы, в которые входят несколько слов и знаков препинания. Например, всё это может выглядеть так: #!/bin/bash
for var in first "the second" "the third" "I’ll do it"
do
echo "This is: $var"
done
Инициализация цикла списком, полученным из результатов работы командыЕщё один способ инициализации цикла for заключается в передаче ему списка, который является результатом работы некоей команды. Тут используется подстановка команд для их исполнения и получения результатов их работы. #!/bin/bash
file="myfile"
for var in $(cat $file)
do
echo " $var"
done
Тут надо учесть, что подобный подход, если ожидается построчная обработка данных, не сработает для файла более сложной структуры, в строках которого может содержаться по несколько слов, разделённых пробелами. Цикл будет обрабатывать отдельные слова, а не строки. Что, если это совсем не то, что нужно? Разделители полейПричина вышеописанной особенности заключается в специальной переменной окружения, которая называется IFS (Internal Field Separator) и позволяет указывать разделители полей. По умолчанию оболочка bash считает разделителями полей следующие символы:
Для того, чтобы решить проблему, можно временно изменить переменную среды IFS . Вот как это сделать в bash-скрипте, если исходить из предположения, что в качестве разделителя полей нужен только перевод строки: IFS=$"\n"
#!/bin/bash
file="/etc/passwd"
IFS=$"\n"
for var in $(cat $file)
do
echo " $var"
done
Разделителями могут быть и другие символы. Например, выше мы выводили на экран содержимое файла /etc/passwd . Данные о пользователях в строках разделены с помощью двоеточий. Если в цикле нужно обрабатывать подобные строки, IFS можно настроить так: Обход файлов, содержащихся в директорииОдин из самых распространённых вариантов использования циклов for в bash-скриптах заключается в обходе файлов, находящихся в некоей директории, и в обработке этих файлов.Например, вот как можно вывести список файлов и папок: #!/bin/bash
for file in /home/likegeeks/*
do
if [ -d "$file" ]
then
echo "$file is a directory"
elif [ -f "$file" ]
then
echo "$file is a file"
fi
done
Вот что выведет скрипт.
Обратите внимание на то, как мы инициализируем цикл, а именно - на подстановочный знак «*» в конце адреса папки. Этот символ можно воспринимать как шаблон, означающий: «все файлы с любыми именами». он позволяет организовать автоматическую подстановку имён файлов, которые соответствуют шаблону. При проверке условия в операторе if , мы заключаем имя переменной в кавычки. Сделано это потому что имя файла или папки может содержать пробелы. Циклы for в стиле CЕсли вы знакомы с языком программирования C, синтаксис описания bash-циклов for может показаться вам странным, так как привыкли вы, очевидно, к такому описанию циклов:For (i = 0; i < 10; i++)
{
printf("number is %d\n", i);
}
For ((начальное значение переменной; условие окончания цикла; изменение переменной))
For ((a = 1; a < 10; a++))
#!/bin/bash
for ((i=1; i <= 10; i++))
do
echo "number is $i"
done
Работа цикла в стиле C Цикл whileКонструкция for - не единственный способ организации циклов в bash-скриптах. Здесь можно пользоваться и циклами while . В таком цикле можно задать команду проверки некоего условия и выполнять тело цикла до тех пор, пока проверяемое условие возвращает ноль, или сигнал успешного завершения некоей операции. Когда условие цикла вернёт ненулевое значение, что означает ошибку, цикл остановится.Вот схема организации циклов while Взглянем на пример скрипта с таким циклом: #!/bin/bash
var1=5
while [ $var1 -gt 0 ]
do
echo $var1
var1=$[ $var1 - 1 ]
done
Результат работы цикла while Если не модифицировать переменную $var1 , это приведёт к попаданию скрипта в бесконечный цикл. Вложенные циклыВ теле цикла можно использовать любые команды, в том числе - запускать другие циклы. Такие конструкции называют вложенными циклами: #!/bin/bash
for ((a = 1; a <= 3; a++))
do
echo "Start $a:"
for ((b = 1; b <= 3; b++))
do
echo " Inner loop: $b"
done
done
Вложенные циклы Обработка содержимого файлаЧаще всего вложенные циклы используют для обработки файлов. Так, внешний цикл занимается перебором строк файла, а внутренний уже работает с каждой строкой. Вот, например, как выглядит обработка файла /etc/passwd: #!/bin/bash
IFS=$"\n"
for entry in $(cat /etc/passwd)
do
echo "Values in $entry –"
IFS=:
for value in $entry
do
echo " $value"
done
done
Обработка данных файла Такой подход можно использовать при обработке файлов формата CSV, или любых подобных файлов, записывая, по мере надобности, в переменную окружения IFS символ-разделитель. Управление цикламиВозможно, после входа в цикл, нужно будет остановить его при достижении переменной цикла определённого значения, которое не соответствует изначально заданному условию окончания цикла. Надо ли будет в такой ситуации дожидаться нормального завершения цикла? Нет конечно, и в подобных случаях пригодятся следующие две команды:
Команда breakЭта команда позволяет прервать выполнение цикла. Её можно использовать и для циклов for , и для циклов while: #!/bin/bash
for var1 in 1 2 3 4 5 6 7 8 9 10
do
if [ $var1 -eq 5 ]
then
break
fi
echo "Number: $var1"
done
Досрочный выход из цикла for Вот - то же самое, но уже для цикла while: #!/bin/bash
var1=1
while [ $var1 -lt 10 ]
do
if [ $var1 -eq 5 ]
then
break
fi
echo "Iteration: $var1"
var1=$(($var1 + 1))
done
Команда continueКогда в теле цикла встречается эта команда, текущая итерация завершается досрочно и начинается следующая, при этом выхода из цикла не происходит. Посмотрим на команду continue в цикле for: #!/bin/bash
for ((var1 = 1; var1 < 15; var1++))
do
if [ $var1 -gt 5 ] && [ $var1 -lt 10 ]
then
continue
fi
echo "Iteration number: $var1"
done
Команда continue в цикле for Обработка вывода, выполняемого в циклеДанные, выводимые в цикле, можно обработать, либо перенаправив вывод, либо передав их в конвейер. Делается это с помощью добавления команд обработки вывода после инструкции done .Например, вместо того, чтобы показывать на экране то, что выводится в цикле, можно записать всё это в файл или передать ещё куда-нибудь: #!/bin/bash
for ((a = 1; a < 10; a++))
do
echo "Number is $a"
done > myfile.txt
echo "finished."
Перенаправление вывода цикла в файл Пример: поиск исполняемых файловДавайте воспользуемся тем, что мы уже разобрали, и напишем что-нибудь полезное. Например, если надо выяснить, какие именно исполняемые файлы доступны в системе, можно просканировать все папки, записанные в переменную окружения PATH . Весь арсенал средств, который для этого нужен, у нас уже есть, надо лишь собрать всё это воедино: #!/bin/bash
IFS=:
for folder in $PATH
do
echo "$folder:"
for file in $folder/*
do
if [ -x $file ]
then
echo " $file"
fi
done
done
Поиск исполняемых файлов в папках из переменной PATH ИтогиСегодня мы поговорили о циклах for и while в bash-скриптах, о том, как их запускать, как ими управлять. Теперь вы умеете обрабатывать в циклах строки с разными разделителями, знаете, как перенаправлять данные, выведенные в циклах, в файлы, как просматривать и анализировать содержимое директорий.Если предположить, что вы - разработчик bash-скриптов, который знает о них только то, что изложено в первой части этого цикла статей, и в этой, второй, то вы уже вполне можете написать кое-что полезное. Впереди - третья часть, разобравшись с которой, вы узнаете, как передавать bash-скриптам параметры и ключи командной строки, и что с этим всем делать. Краткое описание разницы в типах циклов: for — будет выполнять действие до тех пор, пока есть объекты для выполнения (например — чтение потока из stdin , файла или функции); Цикл FORРассмотрим такой вариант скрипта с циклом: $ cat loop.sh #!/bin/bash for variable in `ls -1` do echo "$variable" done Синтаксис очень простой и достаточно наглядно показан в примере: for (запускаем цикл) variable (объявляем переменную, над которой будем выполнять действия) in (направляем циклу поток) `ls -1` (команда, которую необходимо выполнить и передать в переменную $variable). Do и done — «тело» цикла, в рамках которых будут выполняться основные действия над полученными данными, а echo "$variable" — непосредственно само действие, выполняемое циклом. Теперь немного изменим пример, и вместо явного указания команды — применим вторую переменную: $ cat loop.sh #!/bin/bash ls=`ls -1` for variable in $ls do echo "$variable" done Теперь команда ls -1 передаётся в отдельной переменной, что позволяет более гибко работать с циклом. Вместо переменной в цикле можно использовать и функцию: $ cat loop.sh #!/bin/bash lsl () { ls -1 } for variable in `lsl` do echo "$variable" done Основное условие цикла for — он будет выполняться до тех пор, пока в переданной ему команде есть объекты для действия. Исходя из примера выше — пока в листинге ls -1 есть файлы для отображения — цикл будет передавать их в переменную и выполнять «тело цикла». Как только список файлов в директории закончится — цикл завершит своё выполнение. Давайте немного усложним пример. В каталоге имеется список файлов: $ ls -1 file1 file2 file3 file4 file5 loop.sh nofile1 nofile2 nofile3 nofile4 nofile5 Нам необходимо выбрать из них только те, которые в названии не имеют слова «no «: $ cat loop.sh #!/bin/bash lsl=`ls -1` for variable in $lsl do echo "$variable" | grep -v "no" done $ ./loop.sh file1 file2 file3 file4 file5 loop.sh В цикле так же можно использовать условные выражения (conditional expressions ) […] для проверки условий и оператор break для прерывания цикла в случае срабатывания условия. Рассмотрим такой пример: $ cat loop.sh #!/bin/bash lsl=`ls -1` for variable in $lsl do if [ $variable != "loop.sh" ] then echo "$variable" | grep -v "no" else break fi done Цикл будет выполняться до тех пор, пока не будет встречен файл loop.sh . Как только выполнение цикла дойдёт до этого файла — цикл будет прерван командой break: $ ./loop.sh file1 file2 file3 file4 file5 Ещё один пример — использование арифметических операций непосредственно перед выполнением тела цикла: $ cat loop.sh #!/bin/bash for ((count=1; count<11; count++)) do echo "$count" done Тут мы задаём три управляющих команды — count=1 , контролирующее условие — пока count меньше 11, и команду для выполнения — count +1: Циклы WHILE и UNTILПростой пример, хорошо демонстрирующий принцип работы цикла while: $ cat loop.sh #!/bin/bash count=0 while [ $count -lt 10 ] do ((count++)) echo $count done Мы задаём переменную $count равной нулю, после чего запускаем цикл whi le с условием «пока $count меньше десяти — выполнять цикл». В теле цикла мы выполняем постфиксный инкремент +1 к переменной $count и результат выводим в stdout . Результат выполнения: $ ./loop.sh 1 2 3 4 5 6 7 8 9 10 Как только значение переменной $count стало 10 — цикл прекратился. Хороший пример «бесконечного» цикла, который демонстрирует работу while: $ cat loop.sh #!/bin/bash count=10 while [ 1 = 1 ] do ((count++)) echo $count done $ ./loop.sh ... 5378 5379 5380 5381 5382 5383 ^C Аналогично, но «в обратную сторону» работает и цикл until: $ cat loop.sh #!/bin/bash count=0 until [ $count -gt 10 ] do ((count++)) echo $count done Тут мы задаём похожее условие, но вместо «пока переменная меньше 10» — указываем «пока переменная не станет больше чем 10». Результат выполнения: $ ./loop.sh 1 2 3 4 5 6 7 8 9 10 11 Если же приведённый выше пример «бесконечного цикла» выполнить с использованием until — о не выведет ничего, в отличии от while: $ cat loop.sh #!/bin/bash count=10 until [ 1 = 1 ] do ((count++)) echo $count done $ ./loop.sh $ Так как «условие » изначально «истинно » — тело цикла выполняться не будет. Как и в цикле for — в while и until можно использовать функции. Для примера — цикл из реально использующегося скрипта, выполняющий проверку статуса сервера Tomcat (PID берётся в системе SLES , в других системах может отличаться), немного упрощенный вариант: $ cat loop.sh #!/bin/bash check_tomcat_status () { RUN=`ps aux | grep tomcat | grep -v grep | grep java | awk "{print $2}"` } while check_tomcat_status do if [ -n "$RUN" ] then printf "WARNING: Tomcat still running with PID $RUN." else printf "Tomcat stopped, proceeding...nn" break fi done Результат выполнения: $ ./loop.sh WARNING: Tomcat still running with PID 14435 26548.WARNING: Tomcat still running with PID 14435 26548.WARNING: Tomcat still running with PID 14435 26548.WARNING: Tomcat still running with PID 14435 26548.WARNING: Tomcat still running with PID 14435 26548.WARNING: Tomcat still running with PID 14435 26548.WARNING: Tomcat still running with PID 14435 26548.WARNING: Tomcat still running with PID 14435 Полный вариант: Check_tomcat_status () { RUN=`ps aux | grep tomcat | grep -v grep | grep java | awk "{print $2}"` } while check_tomcat_status; do if [ -n "$RUN" ] then printf "WARNING: Tomcat still running with PID $RUN. Stop it? " answer "Stopping Tomcat..." "Proceeding installation..." && $CATALINA_HOME/bin/shutdown.sh 2&>1 /dev/null || break sleep 2 if [ -n "$RUN" ] then printf "Tomcat still running. Kill it? " answer "Killing Tomcat..." "Proceeding installation...n" && kill $RUN || break sleep 2 fi else printf "Tomcat stopped, proceeding...nn" break fi done Функция answer описывалась в статье , но тут используется немного улучшенный вариант: Answer () { while read response; do echo case $response in |) printf "$1n" return 0 break ;; |) printf "$2n" return 1 break ;; *) printf "Please, enter Y(yes) or N(no)! " esac done } Тут можно было использовать как while , так и until — но не цикл for, так как for сработал бы один раз (получил PID — и завершился). Циклы это крайне удобная штука при написании любых программ или скриптов, скорее даже необходимая. Они позволяют нам выполнять некоторый участок кода заданное количество раз. Естественно в bash есть несколько видов циклов. Мы опишем циклы for in, for, while, until . Хотя for in и for считаются разным синтаксисом одного оператора, на мой взгляд они отличаются друг от друга больше чем while от until. Цикл со счетчиком for in :Цикл for in
это цикл со счётчиком. Блок кода находящийся в теле цикла повторяется столько раз, сколько значений содержится в списке оператора for in при том, при каждом повторе переменная счётчика (тут она названа var, но естественно можно называть её как угодно) имеет значение следующего элемента списка. Синтаксис:
Пример:
Оператор цикла for имеет ещё один способ записи - очень похожий на синтаксис оператора for в языке C. В этом случае при инициализации счётчиков задаются начальные значения переменных или одной переменной и после каждого прохода цикла проверяется условие, если проверка возвращает истину, то начинается следующий проход цикла. В блоке <приращение счётчиков> значение наших переменных счётчиков обязательно должны изменятся (не обязательно в большую сторону) так чтобы при проверки условия рано или поздно мы получили значение лож, иначе цикл никогда не закончится. Очень удобный и главное привычный вариант, в случае если какую либо операцию нужно повторить заданное количество раз. С подобный синтаксис:
Пример:
Цикл while:Это достаточно простая конструкция, которая проверяет условие стоящее за оператором while
и в случае истинности этого условия выполняет блок команд находящийся между словами do и done и затем опять переходит к проверки условия. В случае если проверка вернет лож, то цикл заканчивается и начинаю выполнятся команды следующие за done
. Нужно обязательно следить за тем чтобы <проверка условия> зависела от кода выполняющегося в цикле иначе, если результат проверки не изменяется вы получите бесконечный цикл. Синтаксис:
Пример:
Оператор while
может иметь несколько условий. Но только последнее из них определяет возможность продолжения цикла. В этом случае синтаксис оператора цикла будет отличатся от обычного. <условиеN> Цикл until:Оператор until
очень похож на while, он тоже вычисляет условие, но выполняет тело цикла в случае если результатом вычисления будет лож. Может показаться непривычным, но until вычисляет условие перед первым проходом цикла, как и while, а не после него. Как и в случае с циклами for/in, при размещении ключевого слова do в одной строке с объявлением цикла, необходимо вставлять символ ";" перед do. Синтаксис:
Пример:
Наверное пока хватит. :)
Новые статьи:
0 Meeran Bala-Kumaran Я действительно пытаюсь понять, почему этот цикл while никогда не заканчивается, когда цикл начинается, моя переменная LOC установлена в Testing/, которая является каталогом, который я создал для тестирования этой программы, имеет следующий макет: Я хочу, чтобы цикл заканчивался, как только у всех Каталогов была применена функция "count". Я проверил функцию подсчета, и она не создает бесконечный цикл Я попытался запустить алгоритм вручную PARSE=1 LOC=$LOC/ count AVAILABLEDIR=$(ls $LOC -AFl | sed "1 d" | grep "/$" | awk "{ print $9 }") while [ $PARSE = "1" ] do if [[ ${AVAILABLEDIR[@]} == "" ]]; then PARSE=0 fi DIRBASE=$LOC for a in ${AVAILABLEDIR[@]}; do LOC="${DIRBASE}${a}" LOCLIST="$LOCLIST $LOC" count done for a in ${LOCLIST[@]}; do TMPAVAILABLEDIR=$(ls $a -AFl | sed "1 d" | grep "/$" | awk "{ print $9 }") PREPEND=$a if [[ ${TMPAVAILABLEDIR[@]} == "" ]]; then continue fi for a in ${TMPAVAILABLEDIR[@]}; do TMPAVAILABLEDIR2="$TMPAVAILABLEDIR2 ${PREPEND[@]}${a}" done NEWAVAILABLEDIR="$NEWAVAILABLEDIR $TMPAVAILABLEDIR2" done AVAILABLEDIR=$NEWAVAILABLEDIR NEWAVAILABLEDIR="" LOC="" done Я действительно борется, и любой вклад был бы весьма признателен, я пытался понять это в течение последних двух часов. bash infinite-loop 4 ответаВы должны попробовать запустить скрипт с аргументом -x или записать его в первую строку: #!/bin/bash -x Затем он сообщает вам все, что он делает. В этом случае вы можете заметить две ошибки: Вы никогда не перезагружаете TMPAVAILABLEDIR2 Вы также делаете ls на обычных файлах. Если вы действительно должны избегать рекурсии, попробуйте это, полностью без рекурсии: #!/bin/bash count() { echo counting "$1" } todo=(Testing) while test ${#todo[@]} != 0 do doit=("${todo[@]}") todo=() for dir in "${doit[@]}" do for entry in "$dir"/* # if dir is empty, this shows an entry named "*" do test -e "$entry" || continue # skip the entry "*" of an empty dir count "$entry" test -d "$entry" || continue todo+=("$entry") done done done Однако, пожалуйста, скажите мне, почему вы не можете использовать рекурсию? Это своего рода аллергия? Обет? Существуют ли какие-либо локальные законы против рекурсивного программного обеспечения, где вы живете? Вы написали, что хотите выполнить "подсчет" на всех режках. Посмотрите варианты поиска: Find $LOC -type d | while read dir; do cd $LOC cd ${dir} count done или короче (когда ваш счетчик функций принимает каталог как параметр 1) Find $LOC -type d | xargs count Теперь я вижу, что вы не хотите использовать find или ls -R (рекурсивная функция). Затем вы должны сделать свою собственную рекурсивную функцию, наподобие Function parseDir { ls -d */ $1 | while read dir; do count parseDir $1/$dir done } Я понятия не имею, будет ли это работать, но его интересный вопрос, о котором я не мог перестать думать. Удачи While true ; do for word in "$(echo *)" ; do if [[ -d "$word" ]] ; then d[$((i++))]="$PWD"/"$word" elif [[ -f "$word" ]] ;then f[$((j++))]="$PWD"/"$word" fi done [[ $k -gt $i ]] && cd .. cd "$d[$((k++))]" || break done |
Популярное:
Новое
- Путеводитель по системам для создания инсталляторов
- ESET NOD32 Antivirus скачать бесплатно русская версия
- Picmonkey — быстрый онлайн фоторедактор Frames
- Как построить график в Маткаде (Mathcad)?
- Рейтинг: «Лучший конструктор лендингов Платформа lp конструктор для создания лендингов
- Собрал файл сервер для 1с
- Обработка для выгрузки справочников из 1с 8
- Система компоновки данных - практика разработкиСКД Консоль - изучение Системы Компоновки Данных OnLine
- История почты и почтовых марок чили Какие бывают трек номера Почты Чили
- Как в Chrome включить или упаковать в CRX-архив расширение не из Chrome Web Store