Экспортировать бесполезно, она все равно останется локальной.
Что вообще значит "экспорт переменной"? У каждого запущенного процесса есть свой набор переменных окружения. Запускаем мы из скрипта какую-нибудь программу - этой программе будет передана область памяти с копиями всех экспортированных переменных.
А что значит "выполняется в подоболочке"? Да почти то же самое. Запускается еще несколько экземпляров bash, и уже они выполняют каждый свою команду из конвейера. Но поскольку тут явного вызова нет, (fork без exec) то ему достаются копии всех переменных, не только экспортированных. Но именно копии переменных! Как только подоболочка завершилась, эти копии в любом случае потеряются.
А почему так делается? Да потому что для перенаправления вывода одной команды на ввод другой они должны выполняться одновременно, то есть выполняться они будут двумя разными копиями bash - подоболочками.
В вашем примере, запустил bash скрипт, а там сразу перенаправление. Тут же запустились еще две копии bash, первая пошла выполнять цикл, а вторая yad. Но после того, как подоболочка, выполняющая цикл, завершилась, все ее переменные, разумеется, пропали. Существуют они только до " | ", поэтому, когда я поставил echo $Y >&2
до " | ", то Y вывелся.
То есть, нужно сделать так, чтобы все использование переменной Y происходило в одной подоболочке, до перенаправления вывода конвейером.
Или есть еще такой метод (возможно, не во всех версиях сработает, у меня работает нормально):
#!/bin/bash
exec 3> >(yad --progress)
Y=0
for X in 10 20 30 40 50 60 70 80 90 100.
do
echo $X% >&3
Y=$[$Y+1]
sleep 1
done
echo Y=$Y
exec 3> >(yad --progress) означает "открыть в текущем интерпретаторе дескриптор 3 на запись и перенаправить его в отдельно запущенный процесс yad, где он будет стандартным вводом"
Довольно мудрено выглядит, но зато позволяет избавиться от конвейера, в результате все остальное будет выполняться в текущей оболочке и переменные не потеряются. Все, что нужно отправить в yad в этом случае надо писать в 3 дескриптор: echo $X% >&3