2013-09-03 2 views
0

Я пишу, что должно быть простой функцией, которая выводит выходные данные/proc/[pid]/maps и записывает их в CSV. Я бы хотел записать общий размер всех карт внизу.Bash: странная проблема с переменной областью

Вот функция:

output_MAPS() 
{ 

    { 
    local total=0 
    echo "total , size , size_hex , start , end , perms , offset , dev , inode , path" 
    echo "$1" | while read line ; do 
     local start="$(echo "$line"| awk '{print $1}'| awk 'BEGIN { FS="-" } { print $1 }')" 
     local end="$(echo "$line"| awk '{print $1}'| awk 'BEGIN { FS="-" } { print $2 }')" 
     local perms="$(echo "$line"| awk '{print $2}')" 
     local offset="$(echo "$line"| awk '{print $3}')" 
     local dev="$(echo "$line"| awk '{print $4}')" 
     local inode="$(echo "$line"| awk '{print $5}')" 
     local path="$(echo "$line"| awk '{print $6}')" 
     local size=$((0x$end - 0x$start)) 
     local size_hex="$(printf "%X" "$size")" 
     local tot_size=$(($tot_size + $size)) 
     echo "$tot_size , $size , $size_hex , $start , $end , $perms , $offset , $dev , $inode , $path" 
     total="$tot_size" 
    done 
    echo "TOTAL $total :: $tot_size" 
    }> "$outputdir/$4_$3_$2.csv" 
} 

и вот последние несколько строк вывода:

114282496 , 20480 , 5000 , 2aaab14b0000 , 2aaab14b5000 , rw-p , 2aaab14b0000 , 00:00 , 0 , 
170688512 , 56406016 , 35CB000 , 2aaab14b5000 , 2aaab4a80000 , r--p , 00000000 , 08:02 , 3702398 , /usr/lib/locale/locale-archive 
170717184 , 28672 , 7000 , 2aaab4a80000 , 2aaab4a87000 , r--s , 00000000 , 08:02 , 4000735 , /usr/lib64/gconv/gconv-modules.cache 
170721280 , 4096 , 1000 , 2aaab4a87000 , 2aaab4a88000 , rw-p , 2aaab4a87000 , 00:00 , 0 , 
170811392 , 90112 , 16000 , 7ffffffe9000 , 7ffffffff000 , rw-p , 7ffffffe8000 , 00:00 , 0 , [stack] 
179200000 , 8388608 , 800000 , ffffffffff600000 , ffffffffffe00000 , ---p , 00000000 , 00:00 , 0 , [vsyscall] 
TOTAL 0 :: 

Мы можем видеть из первого столбца, который я вычислительный в общей сложности, но я просто не могу 'получить значение из цикла, даже когда я назначаю его переменной, объявленной за пределами. Какая глупость я делаю?

+0

Обратите внимание, что 'local' не работает так, как вы ожидаете (хотя это не повлияет на код, который вы написали). Переменная может быть сделана только локально для функции; новая область не определяется конструкциями, такими как группа команд или цикл while. – chepner

ответ

2

Проблема в том, что вы прокладываете трубопровод в петлю while. Цикл выполняется в подоболочке, и когда цикл заканчивается, все переменные, определенные в нем, отбрасываются. Вот почему вы видите, что tot_size пуст.

Вместо трубы, использование перенаправления, как показано ниже:

while read line ; do 
    local start="$(echo "$line"| awk '{print $1}'| awk 'BEGIN { FS="-" } { print $1 }')" 
    local end="$(echo "$line"| awk '{print $1}'| awk 'BEGIN { FS="-" } { print $2 }')" 
    local perms="$(echo "$line"| awk '{print $2}')" 
    local offset="$(echo "$line"| awk '{print $3}')" 
    local dev="$(echo "$line"| awk '{print $4}')" 
    local inode="$(echo "$line"| awk '{print $5}')" 
    local path="$(echo "$line"| awk '{print $6}')" 
    local size=$((0x$end - 0x$start)) 
    local size_hex="$(printf "%X" "$size")" 
    local tot_size=$(($tot_size + $size)) 
    echo "$tot_size , $size , $size_hex , $start , $end , $perms , $offset , $dev , $inode , $path" 
    total="$tot_size" 
done <<< "$1" 

См: BashFAQ/024 для подробного объяснения этого вопроса.

+0

Oooh! Спасибо за это: я не понимал, что цикл был в подоболочке. Мне нравится изучать вещи :-) – hardcode57

Смежные вопросы