Когда вы запускаете скрипт в обычном режиме (т. Е. Он находится в вашем PATH
и вы просто вводите его имя или вы указываете явный путь к нему, например ./depthScript), он запускается как подпроцесс текущей оболочки. Это важно, потому что у каждого процесса есть свои переменные. Переменные также бывают двух видов: переменные оболочки (которые доступны только в этом одном процессе) и переменные среды (значения которых экспортируются в подпроцессы, но не копируются из них). И в зависимости от того, где вы хотите, чтобы значение переменной было доступно, есть три различных способа их определения:
# By default, variables are shell variable that's only defined in this process:
shellvar=something
# `export` puts a variable into the environment, so it'll be be exported to subprocesses.
# You can export a variable either while setting it, or as a separate operation:
export envvar=something
export anotherenvvar
anotherenvvar=something
# You can also prefix a command with a variable assignment. This makes an
# environment variable in the command process's environment, but not the current
# shell process's environment:
prefixvar=something ./depthScript $dir/$i
С учетом вышеуказанных заданий:
shellvar
определено в текущем процессе оболочки, но не в любом другом процессе (включая подпроцесс, созданный для запуска глубины скрипта).
envvar
и anotherenvvar
будут унаследованы подпроцессом (и его подпроцессами, и всеми подпроцессами для более поздних команд), но любые изменения, внесенные в него в этих подпроцессах, вообще не влияют на текущий процесс.
prefixvar
доступно только в подпроцессе, созданном для запуска глубинного скрипта (и его подпроцессов), но не в текущем процессе оболочки или любых других его подпроцессах.
Краткое резюме: это беспорядок из-за структуры процесса, и в результате лучше всего избегать даже попыток передавать значения между сценариями (или различными вызовами одного и того же сценария) в переменных. Используйте переменные окружения для настроек и такие, которые вы хотите быть общедоступными (но не нужно сильно менять). Используйте переменные оболочки для вещей, локальных для определенного вызова скрипта.
Итак, как вы должны передавать значения глубины? Ну, стандартный способ - для каждого скрипта (или команды) выводить свои выходные данные в «стандартный вывод», и тогда все, что использует скрипт, может записывать свои выходные данные либо в файл (command >outfile
), либо в переменную (var=$(command)
) , Я бы порекомендовал последнее в этом случае:
depth=$(./depthScript "$dir/$i")
if ((depth > max)) ; then
max=$depth
fi
Некоторые другие рекомендации:
- Подумайте о своем контроле и потоке данных. Текущий скрипт проходит по всем подкаталогам, а затем в конце запускает единственную проверку для самого глубокого подкаталога. Но вам нужно проверить каждый подкаталог по отдельности, чтобы увидеть, является ли он глубже текущего максимума, и в конце сообщить о самом глубоком из них.
- Двойная кавычка вашей переменной ссылки (как я сделал с
"$dir/$i"
выше) Ссылки на переменные без кавычек могут быть разбиты на слова и расширены подстановочными знаками, что является источником большого горя. Похоже, вам нужно оставить $sub
без кавычек, потому что вам нужно , чтобы разделить его на слова, но это сделает сценарий неспособным справиться с именами каталогов с пробелами. См. BashFAQ # 20: «Как я могу найти и безопасно обрабатывать имена файлов, содержащие переводы строк, пробелы или оба?»
- Тест
if [ -n "$sub" ] ; then
не имеет значения. Если $sub
пусто, цикл никогда не запустится.
- В сценарии оболочки относительные пути (например,
./depthScript
) относятся к любому рабочему каталогу родительского процесса, , а не к местоположению сценария. Если кто-то запускает ваш скрипт из другого каталога, ./depthScript
не будет работать. Вместо этого используйте "$BASH_SOURCE"
. См. BashFAQ # 28: «Как определить местоположение моего скрипта? Я хочу прочитать некоторые файлы конфигурации из того же места».
- При попытке устранения неполадок в скрипте может помочь поставить
set -x
перед проблемным разделом. Это заставляет оболочку печатать каждую команду во время ее выполнения, чтобы вы могли видеть, что происходит.
- Запустите ваши скрипты через shellcheck.net - это укажет на множество распространенных ошибок.