Согласно справочной странице bash каждая команда в конвейере выполняется в подоболочке. То есть ваш цикл while выполняется в подоболочке, и изменяется только значение переменной max в этой подоболочке.
Переменные подоболочек не передаются обратно вызывающей оболочке, которая выполняет команду echo и, таким образом, все еще видит начальное нулевое значение.
Если вы запускаете эхо в одной и той же подоболочке (обратите внимание на фигурные скобки), оно будет работать:
max=0
cat tmp|{
while read line
do
temp=$(echo $line|tr -d "\n"|wc -c)
if [ $temp -gt $max ];then
max=$temp
fi
done
echo -n tmp $max
}
Если вам нужно значение для дальнейших вычислений во внешней оболочке, вам необходимо использовать подстановку команд, например:
max=0
max=$(cat tmp|{
while read line
do
temp=$(echo $line|tr -d "\n"|wc -c)
if [ $temp -gt $max ];then
max=$temp
fi
done
echo -n $max
})
echo tmp $max