LINUX.ORG.RU

История изменений

Исправление AITap, (текущая версия) :

Ваша функция searchpath() не принимает аргументов. Задачу наверняка можно решить проще, если передавать состояние через них, не полагаясь на глобальные переменные, которые сохраняют свои значения от вызова к вызову.

Возьмите любой учебник по программированию, например, Столяров, 2021, т.1 §2.3.7 и §2.11 и изучите, как обычно устроены рекурсивные программы. Суть в том, чтобы облегчить себе задачу, складывая состояние в локальные переменные на стеке. Функция searchpath может вызывать себя несколько раз, и в каждом таком вызове будет своя переменная unit, depth, choose со своим значением. Чтобы вернуться на предыдущий шаг, достаточно сделать return, и локальные переменные сами примут свои значения на момент предыдущего вызова функцией самой себя.

list=$(ls -l /parent/"$unit")

Это довольно хрупко. declare -a list=(/parent/"$unit"/*) - и теперь в массиве ${list[@]} хранятся отдельные записи из Вашей директории.

choose=$(echo "$list" | sed -n "$var"p)

К элементам массива можно обращаться как "${list[$var]}".

if ls -l /parent/"$unit""$choose" | grep "/"; then #проверяет является ли строка каталогом

Изучите help test. Проверка на каталог - это test -d "$path_to_whatever".

if [ "$var" = "0" ]; then depth=$(( $depth - 1 )); searchpath; fi #Если выбор 0, программа должна уменьшить глубину (как вариант), затем заново запустить функцию

В строке if [ «$var» = «0» ]; then должно быть что-то ещё, например $unit=$unit минус предыдущий $choose, то есть вернуть его в состояние до предыдущего прохода. Но как быть с родителем который ещё старше? Для этого нужно как-то обращаться к $path1

Если Вы будете использовать аргументы функций и локальные переменные, Вам не придётся вручную возвращать значения глобальных переменных к предыдущему значению перед выходом из функции searchpath (там должен быть return, а не searchpath, иначе функция будет бесконечно вызывать саму себя и никогда не завершится). См. также bashdb - отладчик для bash-скриптов с пошаговым проходом и другими удобствами.

Как быть с родителями и их родителями? Вызывая саму себя, searchpath может передавать себе массив родителей плюс текущий unit:

# вызов: searchpath "$foo" "$bar" "${parents[@]}"
searchpath() {
 local foo bar
 foo="$1"; shift
 bar="$2"; shift
 declare -a parents=("$@")
 # ...
 # настало время вызвать саму себя, добавив к массиву parents ещё одно значение на время этого вызова
 f "$foo" "$bar" "$current_unit" "${parents[@]}" # $current_unit станет первым элементом $parents[@] внутри этого вызова
 # ...
}

Тогда первый родитель получается "${parents[0]}", второй - "${parents[1]}", а их количество - ${#parents}.

rm /parent/"$unit""$choose" #удаляет её
searchpath # и запускает новый проход, в том же каталоге, где была найдена запись

А не получится ли выполнить работу этой функции при помощи find с некоторыми условиями и флагом -delete для удаления найденных файлов? Или Вам нужна интерактивность?

Исправление AITap, :

Ваша функция searchpath() не принимает аргументов. Задачу наверняка можно решить проще, если передавать состояние через них, не полагаясь на глобальные переменные, которые сохраняют свои значения от вызова к вызову.

Возьмите любой учебник по программированию, например, Столярова, 2021, т.1 §2.3.7 и §2.11 и изучите, как обычно устроены рекурсивные программы. Суть в том, чтобы облегчить себе задачу, складывая состояние в локальные переменные на стеке. Функция searchpath может вызывать себя несколько раз, и в каждом таком вызове будет своя переменная unit, depth, choose со своим значением. Чтобы вернуться на предыдущий шаг, достаточно сделать return, и локальные переменные сами примут свои значения на момент предыдущего вызова функцией самой себя.

list=$(ls -l /parent/"$unit")

Это довольно хрупко. declare -a list=(/parent/"$unit"/*) - и теперь в массиве ${list[@]} хранятся отдельные записи из Вашей директории.

choose=$(echo "$list" | sed -n "$var"p)

К элементам массива можно обращаться как "${list[$var]}".

if ls -l /parent/"$unit""$choose" | grep "/"; then #проверяет является ли строка каталогом

Изучите help test. Проверка на каталог - это test -d "$path_to_whatever".

if [ "$var" = "0" ]; then depth=$(( $depth - 1 )); searchpath; fi #Если выбор 0, программа должна уменьшить глубину (как вариант), затем заново запустить функцию

В строке if [ «$var» = «0» ]; then должно быть что-то ещё, например $unit=$unit минус предыдущий $choose, то есть вернуть его в состояние до предыдущего прохода. Но как быть с родителем который ещё старше? Для этого нужно как-то обращаться к $path1

Если Вы будете использовать аргументы функций и локальные переменные, Вам не придётся вручную возвращать значения глобальных переменных к предыдущему значению перед выходом из функции searchpath (там должен быть return, а не searchpath, иначе функция будет бесконечно вызывать саму себя и никогда не завершится). См. также bashdb - отладчик для bash-скриптов с пошаговым проходом и другими удобствами.

Как быть с родителями и их родителями? Вызывая саму себя, searchpath может передавать себе массив родителей плюс текущий unit:

# вызов: searchpath "$foo" "$bar" "${parents[@]}"
searchpath() {
 local foo bar
 foo="$1"; shift
 bar="$2"; shift
 declare -a parents=("$@")
 # ...
 # настало время вызвать саму себя, добавив к массиву parents ещё одно значение на время этого вызова
 f "$foo" "$bar" "$current_unit" "${parents[@]}" # $current_unit станет первым элементом $parents[@] внутри этого вызова
 # ...
}

Тогда первый родитель получается "${parents[0]}", второй - "${parents[1]}", а их количество - ${#parents}.

rm /parent/"$unit""$choose" #удаляет её
searchpath # и запускает новый проход, в том же каталоге, где была найдена запись

А не получится ли выполнить работу этой функции при помощи find с некоторыми условиями и флагом -delete для удаления найденных файлов? Или Вам нужна интерактивность?

Исходная версия AITap, :

Ваша функция searchpath() не принимает аргументов. Задачу наверняка можно решить проще, если передавать состояние через них, не полагаясь на глобальные переменные, которые сохраняют свои значения от вызова к вызову.

Возьмите любой учебник по программированию, например, Столярова, 2021, т.1 §2.3.7 и §2.11 и изучите, как обычно устроены рекурсивные программы. Суть в том, чтобы облегчить себе задачу, складывая состояние в локальные переменные на стеке. Функция searchpath может вызывать себя несколько раз, и в каждом таком вызове будет своя переменная unit, depth, choose со своим значением. Чтобы вернуться на предыдущий шаг, достаточно сделать return, и локальные переменные сами примут свои значения на момент предыдущего вызова функцией самой себя.

list=$(ls -l /parent/"$unit")

Это довольно хрупко. declare -a list=(/parent/"$unit"/*) - и теперь в массиве ${list[@]} хранятся отдельные записи из Вашей директории.

choose=$(echo "$list" | sed -n "$var"p)

К элементам массива можно обращаться как "${list[$var]}".

if ls -l /parent/"$unit""$choose" | grep "/"; then #проверяет является ли строка каталогом

Изучите help test. Проверка на каталог - это test -d "$path_to_whatever".

if [ "$var" = "0" ]; then depth=$(( $depth - 1 )); searchpath; fi #Если выбор 0, программа должна уменьшить глубину (как вариант), затем заново запустить функцию

В строке if [ «$var» = «0» ]; then должно быть что-то ещё, например $unit=$unit минус предыдущий $choose, то есть вернуть его в состояние до предыдущего прохода. Но как быть с родителем который ещё старше? Для этого нужно как-то обращаться к $path1

Если Вы будете использовать аргументы функций и локальные переменные, Вам не придётся вручную возвращать значения глобальных переменных к предыдущему значению перед выходом из функции searchpath (там должен быть return, а не searchpath, иначе функция будет бесконечно вызывать саму себя и никогда не завершится). См. также bashdb - отладчик для bash-скриптов с пошаговым проходом и другими удобствами.

Как быть с родителями и их родителями? Вызывая саму себя, searchpath может передавать себе массив родителей плюс текущий unit:

# вызов: searchpath "$foo" "$bar" "${parents[@]}"
searchpath() {
 local foo bar
 foo="$1"; shift
 bar="$2"; shift
 declare -a parents=("$@")
 # ...
 # настало время вызвать саму себя, добавив к массиву parents ещё одно значение на время этого вызова
 declare -a more_parents=("$current_unit" "${parents[@]}")
 f "$foo" "$bar" "${more_parents[@]}"
 # ...
}

Тогда первый родитель получается "${parents[0]}", второй - "${parents[1]}", а их количество - ${#parents}.

rm /parent/"$unit""$choose" #удаляет её
searchpath # и запускает новый проход, в том же каталоге, где была найдена запись

А не получится ли выполнить работу этой функции при помощи find с некоторыми условиями и флагом -delete для удаления найденных файлов? Или Вам нужна интерактивность?