Объем переменных при вызове функции из find

В сценарии bash я определяю функцию, вызываемую из find . Проблема в том, что область переменных не распространяется на функцию. Как получить доступ к переменным из функции? Вот пример:

 variable="Filename:" myfunction() { echo $variable $1 } export -f myfunction find . -type f -exec bash -c 'myfunction "{}"' \; 

Это будет выводить имена файлов, но без строки «Имя файла:».

Может быть, лучший способ вызвать функцию из find , чтобы она вызывалась для каждого файла, который find находки, и переменные все еще определены?

4 Solutions collect form web for “Объем переменных при вызове функции из find”

Вы можете объявить variable как переменную среды, т. Е.

 export variable="Filename:" 

Не ответ на ваш вопрос, но не делайте:

 find . -type f -exec bash -c 'myfunction "{}"' \; 

Помимо того, что он не переносимый, он также очень опасен, потому что имена файлов в конечном итоге интерпретируются bash как код оболочки. Рассмотрим, например, что произойдет, если там будет файл с именем $(rm -rf ~) . Напиши это:

 find . -type f -exec bash -c 'myfunction "$1"' find+bash {} \; 

Или даже лучше (чтобы не запускать один bash за файл):

 find . -type f -exec bash -c 'for file do myfunction "$file"; done' find+bash {} + 

Теперь ответ на ваш вопрос будет по теме:

Вы можете сделать:

 { find . -type f -exec printf '%s\0' {} + | while IFS= read -ru3 -d '' file; do myfunction "$file"; done 3<&0 <&4 4<&-; } 4<&0 

Таким образом, вы вызываете myfunction в текущей оболочке bash , поэтому вам не нужно экспортировать myfunction или запускать дополнительные оболочки bash .

Если ваша find поддерживает предикат -print0 (например, GNU, busybox и некоторые BSD find s), вы можете заменить -exec printf '%s\0' {} + на -print0

Я сделал бы это, как следует

 #!/bin/bash myfunction() { local var="Filename: " local file=$1 echo "$var" "$file" } export -f myfunction find . -type f -exec bash -c 'myfunction {}' \; 

Объявите vars как локальный и передайте '{}' функции, которая является первым позиционным параметром $1 .

Когда вы назначаете переменную, она начинается как переменная оболочки. Чтобы получить переменную окружения, которая передается подпроцессам, вам необходимо экспортировать ее.

 variable="Filename:" export variable 

Вы можете поставить присвоение в той же строке, что и export : export variable="Filename:" .

Переменная будет видна для оболочек, запущенных find , но не для функций. В bash вы также можете экспортировать функции. Эта возможность отсутствует в ksh, тире и других оболочках, которые часто используются как sh потому что они быстрее и компактнее.

 export -f myfunction # bash only 

Никогда не используйте {} внутри строки в find -exec … (или xargs … ), если вы не знаете, что ваши имена файлов являются буквенно-цифровыми. Если в именах файлов есть специальные символы, они будут разбираться как таковые внутренней оболочкой. Вместо этого передайте имена файлов в командной строке оболочки.

 find . -type f -exec bash -c 'for x; do myfunction "$x"; done' _ {} + 

С оболочками, отличными от bash, определите функцию во внутренней оболочке или просто поместите ее код напрямую.

В качестве альтернативы, в bash, вы можете использовать рекурсивное globbing вместо find. Помните, что bash пересекает символические ссылки на каталоги.

 variable="Filename:" myfunction () { … } shopt -s globstar dotglob for x in **/*; do if [[ -f $x ]]; then myfunction "$x"; fi done 
  • захватить из текстового файла диапазон с использованием двух переменных в качестве начального и конечного параметров
  • dirname и basename против расширения параметров
  • Присвоение нового значения непосредственно в индекс символа значения в массиве с zsh
  • Сценарий Bash для заполнения шаблона
  • Невозможно выполнить сценарий Bash, если / while
  • bash - определяющие переменные с VAR = $ {: - по умолчанию}
  • Как сохранить статус последнего выхода после теста
  • Расширение «$ @» для пользовательских переменных
  • Несколько входов в одной команде
  • Могу ли я определить тип переменной awk?
  • Использование sed в сценарии оболочки с многострочными переменными
  • Linux и Unix - лучшая ОС в мире.