2017-01-30 19 views
0

Мне нужна помощь (снова) после того, как вы, ребята, помогли мне чудесно в прошлый раз. Я пишу скрипт для тестирования своих жестких дисков с помощью SmartCTL. Так что я могу конечно скопировать команды на диск, но это было бы еще более удивительным, если я могу просто установить диски один раз и сценарий делает их один за другим:Bash: использовать переменную в цикле

#!/bin/bash 
date=`date +%d-%m-%Y-%T` 
touch /var/log/disk/Disk-health-check-$date 
disks="/dev/sda 
/dev/sdb" 
for disk in disks 
    do 
    wait=$(smartctl -t short $disk | awk '/Please wait/ {print $3}') 
     echo "waiting..." 
     sleep $((wait * 60 + 60)) 
     echo "done" 
     smartctl --log=selftest $disk 
     smartctl -a $disk 
    done 
exit 

Но, к сожалению, он использует только/Dev/sda, а не sdb и т. д. Итак, как я могу это сделать? Спасибо заранее, ребята!

+2

'для диска в $ disks', а не' на диске в disks'. Хотя это и есть плохая практика. –

+2

'disks = (/ dev/sda/dev/sdb)' и использовать 'для диска в '$ {disks [@]}" 'для массива. И исправить все ошибки http://shellcheck.net/ find. –

+2

как другой - используйте 'YYYY-mm-dd' в качестве формата даты. Это стандарт ISO, и, что более важно, его порядок сортировки по ASCII имеет порядок сортировки как дату, что абсолютно не соответствует формату, который вы пытаетесь использовать здесь. Наличие правильного порядка сортировки ASCII облегчает поиск самого старого или новейшего файла или каждого файла старше определенной даты и т. Д. –

ответ

1

Попробуйте это:

#!/bin/bash 
date=$(date +%d-%m-%Y-%T) 
touch /var/log/disk/Disk-health-check-"$date" 
disks=(/dev/sda /dev/sdb) 
for disk in "${disks[@]}" 
    do 
    wait=$(smartctl -t short "$disk" | awk '/Please wait/ {print $3}') 
    echo "waiting..." 
    sleep $((wait * 60 + 60)) 
    echo "done" 
    smartctl --log=selftest "$disk" 
    smartctl -a "$disk" 
    done 
exit 

На основе массивов переменных, описанных здесь: http://wiki.bash-hackers.org/syntax/arrays?s[]=arrays

+0

Гораздо лучше. Я бы предложил вести журналы в stderr, а не в stdout, поскольку они являются статусом (предназначенным для потребления пользователем), а не выходом (для отправки в следующую программу в конвейере), но ничего не происходит на его лице , –

+0

Спасибо за ссылку на spellcheck.net –

+0

err, это «shellcheck», с h, а не p :) –

4

Попробуйте это:

for disk in disks; do 
    echo "$disk" 
done 

Вы увидите, что единственное, что отголоски является disks. Это потому, что вы говорите ему перебирать ровно одно значение, и это значение равно disks.


Чтобы сделать тонко глючный, что вы пытались сделать, вы хотите вместо этого:

for disk in $disks; do 
    echo "$disk" 
done 

Однако, как я уже сказал, что это багги. Допустим, ваш disks переменные были назначены немного по-разному:

disks=' 
/dev/disks/by-label/My Drive 
/dev/disks/by-label/Other Drive 
/dev/disks/by-label/* TEENAGE DAUGHTER'S DRIVE * 
' 

Это будет иметь /dev/disks/by-label/My как одна записи, Drive как следующий - и в * с будет расширено с именами файлов в каталоге вы находитесь когда вы запускаете скрипт. Очевидно, не то, что вы хотите.

Вместо этого используйте массив:

disks=(
    "/dev/disks/by-label/My Drive" 
    "/dev/disks/by-label/Other Drive" 
    "/dev/disks/by-label/* TEENAGE DAUGHTER'S DRIVE *" 
) 

... и перебирать их, как:

for disk in "${disks[@]}"; do 
    echo "Processing: $disk" 
done 
+0

Спасибо, это очень мило. Не могли бы вы объяснить «$ {disks [@]}», как это работает? Я никогда не видел этого раньше, чтобы быть честным. есть ли разница используя ("* диски диск *") или диски = (диск1 диск2)? (Твой и Чак Донахью)? – Florius

+0

Мой ответ и Чака фактически эквивалентны, так как содержание под рукой не требует * необходимости цитирования. 'disks = ("/dev/sda ""/dev/sdb ")' будет работать и в том случае, если имена не содержат пробелов или символов глобуса. Я показываю приведенную выше цитату, чтобы продемонстрировать, как она работает при необходимости с массивом, тогда как она * не будет * работать с 'disks = '"/dev/sda ""/dev/sdb "'' или такой; см. [BashFAQ # 50] (http://mywiki.wooledge.org/BashFAQ/050) для подробного обсуждения режима сбоя. –

+0

Что касается '' $ {disks [@]} "', то это стандартный синтаксис расширения массива - см. [BashFAQ # 5] (http://mywiki.wooledge.org/BashFAQ/005) или вики-хакеры хакеров страницы на массивах, связанных с ответом Чака. –

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