Распечатать переменные из подоболочки в родительскую оболочку

Распечатать переменные из подоболочки в родительскую оболочку

Совсем новичок в Bash и совсем запутался в локальных/глобальных переменных/подоболочках. Я не уверен, почему измененные переменные не выводятся в конце функции — я пытаюсь вывести окончательное количество строк и файлов в конце файла, но если я это делаю, выводится только 0, потому что это локальные переменные. Есть ли способ вывести измененные значения?

count=0
files=0
find . -type f | while IFC= read -r file;
do
   let files=files+1
   wc -l $file
   count=$(($count+$(wc -l < $file)))
   echo "total lines $count ; total files $files"
done
echo $files $count
exit 0

решение1

Да. Но это абсолютно неинтуитивно. Это будет работать, например:

#!/bin/bash
count=0
files=0
while IFS= read -r file;
do
   let files=files+1
   wc -l $file
   count=$(($count+$(wc -l < $file)))
   echo "total lines $count ; total files $files"
done < <(find . -type f )
echo "$files $count"
exit 0

Конструкция <(command)называется«замена процесса»и позволяет вам обрабатывать вывод команды как "файл". Подача его в цикл таким образом заставляет ваш скрипт работать так, как вы ожидаете.

Проблема в использовании вами конвейера ( |), который заставляет цикл while выполняться в отдельной подоболочке, которая не может изменять переменные за ее пределами.

В оболочках, которые не поддерживают эту <()функцию, вы можете выполнить команду(ы) справа от канала в подынтервале и включить финальное эхо в эту подынтервалу:

#!/bin/bash
files=0
find . -type f | {
    while IFC= read -r file;
    do
        let files=files+1
        wc -l $file
        count=$(($count+$(wc -l < $file)))
        echo "total lines $count ; total files $files"
    done
    echo "$files $count"
}

exit 0

Связанный контент