Это фрагмент скрипта bash, который мы используем для мониторинга состояния монтирования на сервере:
OIFS=$IFS
IFS=$'\n'
for mount in $mounts; do
mountcount=$(($mountcount+1))
dev=`echo $mount | awk {'print $1'};`
dir=`echo $mount | awk {'print $2'};`
opts=`echo $mount | awk {'print $4'};`
state=`echo $opts | cut -d ',' -f 1`
if [ "$state" = "ro" ]; then
crit="true"
break
fi
done
IFS=$IFS
$ mounts будет иметь содержимое, похожее на:
rootfs / rootfs rw 0 0
none /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0
none /proc proc rw,nosuid,nodev,noexec,relatime 0 0
none /dev devtmpfs rw,relatime,size=1028136k,nr_inodes=218146,mode=755 0 0
none /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0
fusectl /sys/fs/fuse/connections fusectl rw,relatime 0 0
/dev/disk/by-uuid/f2337686-ec8d-429a-9002-592c564ddbf3 / ext3 rw,relatime,errors=remount-ro,barrier=0,data=ordered 0 0
none /sys/kernel/debug debugfs rw,relatime 0 0
none /sys/kernel/security securityfs rw,relatime 0 0
none /dev/shm tmpfs rw,nosuid,nodev,relatime 0 0
none /var/run tmpfs rw,nosuid,relatime,mode=755 0 0
none /var/lock tmpfs rw,nosuid,nodev,noexec,relatime 0 0
Как вы должны видеть, я разбираю каждую строку на части, чтобы найти компоненты, которые монтируются только для чтения. Функционально это работает абсолютно нормально, однако проблема в том, что мы выполняем это на сотнях серверов, и в настоящее время требуется более секунды (иногда) для прохождения вышеуказанного цикла с вышеуказанными данными.
Я полагаю, что эта проблема вызвана ожиданием при выполнении awk
и cut
, поскольку они являются внешними программами, поэтому мне было интересно, если есть более эффективный способ, с помощью которого можно было бы выполнить ту же функцию. Я не достаточно опытен в bash, чтобы знать внутренние функции, которые могли бы помочь с этим, или достаточно опытен в awk
, чтобы делать все это одной строкой.
Мне кажется, что 3 вызова awk
и 1 вызов cut
могут быть выполнены в 1 строке awk
. Любая помощь с благодарностью!
EDIT
Переменные dev, dir и mountcount используются позже в скрипте для построения вывода.
EDIT
Я изменил сценарий следующим образом: (Все эхо-тесты включены в качестве теста)
mountcount=0
OIFS=$IFS
IFS=$'\n'
for mount in $mounts; do
mountcount=$(($mountcount+1))
echo $mount
echo $mount | read dev dir fs opts
echo $dev
echo $dir
echo $fs
echo $opts
state=`echo $opts | cut -d ',' -f 1`
if [ "$state" = "ro" ]; then
crit="true"
break
fi
done
IFS=$OIFS
И это дает мне следующее:
rootfs / rootfs rw 0 0
fusectl /sys/fs/fuse/connections fusectl rw,relatime 0 0
/dev/disk/by-uuid/1be5b3ae-8239-4177-9af6-22ad0afa662a / ext3 rw,relatime,errors=remount-ro,data=ordered 0 0
/dev/disk/by-uuid/1be5b3ae-8239-4177-9af6-22ad0afa662a /dev/.static/dev ext3 rw,relatime,errors=remount-ro,data=ordered 0 0
devpts /dev/pts devpts rw,relatime 0 0
securityfs /sys/kernel/security securityfs rw,relatime 0 0
Так что read
работает не совсем так, как ожидалось.