Чтобы попытаться объяснить более буквально, чем великий теоретический ответ meuh -, как вы, вероятно, знаете, существует ряд файловых дескрипторов по умолчанию:
0
означает стандартный ввод 1
означает стандартный вывод 2
означает stderr Ваша команда делает следующее:
3>all
открыть новый файловый дескриптор, указывающий на файлall
1> >(tee out >&3)
перенаправить стандартный вывод(1
)на файловый дескриптор, открытый и возвращенный командой tee, как объяснил meuh tee out >&3
перенаправляет свой ввод (, в данном случае стандартный вывод из вашего скрипта )в файл с именем out, и везде, где файловый дескриптор 3
указывает на (, в этом случае файл all)2> >(tee err >&3)
перенаправить stderr(2
)на дескриптор файла, открытый и возвращенный командой tee, как объяснил meuh tee err >&3
перенаправляет свой ввод (, в данном случае stderr из вашего скрипта )в файл с именем err,и везде, где дескриптор файла 3
указывает на (, в этом случае файл все)Судя по вашему комментарию, я думаю, что вас смущает то, что вы ожидаете, что вам нужно будет использовать >>
в качестве оператора перенаправления, если вы хотите добавить вывод в файл.
Здесь дело обстоит иначе, так как все, что вы буквально делаете, это подключаете и stdout, и stderr к файловому дескриптору, который указывает на файл all.
Эффект тот же, что и при выполнении:
./my.sh > all 2>&1
Что сначала перенаправляет stdout в файл all, а затем перенаправляет stderr туда, куда указывает stdout.
Я пришел к этому, если я вас правильно понял, и взяв за пример ответ @Kunasalanda:
This is using bash (or compatible shell) and GNU date. It would fall over on e.g. macOS (non-GNU date).
today=$(date -d $(date +'%Y-%m-%d') +%s)
while read i; do
[[ -z "$i" ]] && continue
date_format=$(echo "$i" | awk -F'.' -vOFS='-' '{print $3,$2,$1}')
convert_date=$(date -d "$date_format" +%s)
if [[ "$convert_date" -ge "$today" ]]; then
expires=$(( ("$convert_date"- "$today")/86400 ))
[[ ! "$expires" -gt 10 ]] && echo $i expires in $expires days
fi
done < file
Выход:
14.08.2019 expires in 0 days
18.08.2019 expires in 4 days
20.08.2019 expires in 6 days
Игнорировать пустые строки
[[ -z "$i" ]] && continue
Отформатируйте от dd.mm.yy
до yyyy-mm-dd
для выполнения операций
date_format=$(echo "$i" | awk -F'.' -vOFS='-' '{print $3,$2,$1}')
Преобразование даты в секунды
convert_date=$(date -d "$date_format" +%s)
Выбирайте только те даты, которые старше сегодняшнего дня
if [[ "$convert_date" -ge "$today" ]]; then
Получить количество дней, в течение которых истечет указанная дата
expires=$(( ("$convert_date"- "$today")/86400 ))
Вывод, только если срок действия не превышает 10 дней
[[ ! "$expires" -gt 10 ]] && echo "$i" expires in "$expires" days