При вычитании таймштампов в цикле, в терминал валятся ошибки

Если в Bash выполнить

let RAZNOST="$(stat -c %Y /dir1/$file) - $(stat -c %Y /dir1/dir2/$file)"

то мы получим разность таймштампов, все работает корректно, всё хорошо.

Но если выполнять эту команду внутри цикла, то в терминале куча ошибок вида -

1609183561: синтаксическая ошибка в выражении (неверный маркер «1609183561 1609183561 1609183561 1609183561 1609183561 1609183561 1609183561 1609183561 1609183561 1609183561 - 1609183544 1609183561 1609183561 1609183561 1609183561 1609183561 1609183561 1609183561 1609183561 1609183561 1609183561»)

При этом цикл отработает нормально, мы получим верный ответ.

            while IFS= read -r l ;

            do

            file=$(grep -o "$l" <(echo "$A1"))

            if  [  $? -eq "0" ] ; then

                   let  X="$(stat -c %Y /dir1/$file) - $(stat -c %Y /dir1/dir2.$file)"
                      if [ "$X" -ge 120 ];then
                            ...
                            do something
                            ...                
                            
                     fi
            else
                    ...
                    do something else
                    ...
            fi

            done < <(echo "$R") 

Это мой первый код в Bash очень хочется понять


Ответы (1 шт):

Автор решения: aleksandr barakin

ошибка у вас состоит в том, что в переменной $file находится несколько слов.

в результате программа stat получает несколько аргументов. и возвращает несколько значений. пример:

$ file="/bin /etc"
$ stat -c %Y $file
1607256826
1609133548

соответственно вместо такого корректного арифметического выражения:

let x="число1 - число2"

вы получаете примерно такое некорректное арифметическое выражение (в приведённом вами примере у вас чисел значительно больше):

let x="число1 число2 - число3 число4"

на что получаете вполне справедливое сообщение об ошибке:

bash: let: x=число1 число2 - число3 число4: syntax error in expression (error token is "число2 - число3 число4")


вероятно, вам стоит использовать ещё один (вложенный) цикл для перебора значений, возвращаемых командой grep -o "$l" <(echo "$A1"). что-нибудь вроде:

files=$(grep -o "$l" <(echo "$A1"))
for file in $files; do
  ...
done

а ещё вместо let можно использовать «нормальное» вычисление арифметического выражения. т.е. вместо:

let x="арифметическое выражение"

использовать:

x=$((арифметическое выражение))
→ Ссылка