Вывод sh для цикла перепутан - PullRequest
1 голос
/ 31 октября 2019

В настоящее время я пишу сценарий, который должен проверять состояние безопасности ATA для каждого устройства, указанного в файле.

Состояние безопасности ATA проверяется с помощью команды smartctl -g security "$drive" | grep -c "ATA Security is:.*NOT FROZEN", которая выводит 0 (заморожено) или1 (не заморожен) и был протестирован.

Сценарий в настоящее время выглядит следующим образом:

# get newline as Seperator
IFS=$(echo)
# get drives
drives=$(cat ./sd-freeze.conf)

# check status for each drive
for drive in $drives
do  
    frozen=$(smartctl -g security "$drive" | grep -c "ATA Security is:.*NOT FROZEN")
    echo "$drive"
    echo "$frozen"
done

sd-freeze.conf содержит это:

/dev/sda
/dev/sdb

Вывод должен быть:

/dev/sda
1
/dev/sdb
1

Но как-то так:

/dev/sda
/dev/sdb
0

Кто-нибудь знает, почему порядок вывода испорчен (оба устройства не заморожены)?

1 Ответ

1 голос
/ 31 октября 2019
# get newline as Seperator
IFS=$(echo)

$(...) убирает все завершающие символы новой строки из строки. Эта строка фактически устанавливает IFS='' вместо IFS=$'\n' по желанию. Означает, что приведенные ниже символы $drives вообще не разделяются. Цикл повторяется только один раз по всей строке $drives.

Возможное исправление - установить IFS=$'\n', чтобы получить эту новую строку, но на самом деле лучше не переопределять IFS глобально. Как говорит мудрый Раймонд Чен : «Не используйте глобальное состояние для управления локальной проблемой».

Чтобы прочитать набор строк в массиве, я бы использовал readarray. Таким образом, на остальную часть сценария это никак не повлияет.

readarray -t drives < sd-freeze.conf

# check status for each drive
for drive in "${drives[@]}"
do  
    frozen=$(smartctl -g security "$drive" | grep -c "ATA Security is:.*NOT FROZEN")
    echo "$drive"
    echo "$frozen"
done
...