Aby potwierdzić każdą linię, jak je czytać, bezpieczny sposób, aby to zrobić, to napisać wyrażenie regularne i użyć BASH_REMATCH
wyodrębnić grupy meczu z niej .
z następującego kodu:
re='^"(.*)" [{]([0-9a-f-]+)[}]$'
while read -r line; do
if [[ $line =~ $re ]]; then
name=${BASH_REMATCH[1]}; uuid=${BASH_REMATCH[2]}
echo "Found VM with name $name and uuid $uuid" >&2
else
echo "ERROR: Could not parse line: $line" >&2
fi
done < <(VBoxManage list runningvms)
... i następnego udawanym realizacji VBoxManage (aby umożliwić ludzie bez VirtualBox odtworzyć test):
VBoxManage() { printf '%s\n' '"UbuntuServer" {7ef01f8d-a7d5-4405-af42-94d85f999dff}'; }
... wyjście w następujący sposób:
Found VM with name UbuntuServer and uuid 7ef01f8d-a7d5-4405-af42-94d85f999dff
Uwaga Zalety tego podejścia:
- Nie zawiera nieuzasadnionych założeń, takich jak wykluczenie maszyn wirtualnych z białymi znakami lub literałów cudzysłowu w ich nazwach z poziomu wsparcia.
- Wykrywa każdą linię, która nie pasuje do oczekiwanego wzorca, zamiast zachowywać się nieprzewidywalnie w obecności takich wartości.
- To nadal działa poprawnie z danymi, które ma pasuje do wzorca, ale ma nieprzewidziane wartości. (Na przykład maszyna wirtualna o nazwie
*
nie będzie miała cichej nazwy zastąpionej nazwą pliku w bieżącym katalogu).
- To nie wymaga zewnętrznych narzędzi do powłoki, takie jak
sed
, cut
, & c, ale opiera się wyłącznie na muszli wbudowane funkcjonalności. - patrz BashFAQ #1 dokumentowania użycia while read
i the bash-hackers' wiki on regular expression matching dokumentowania [[ $string =~ $re ]]
.
"Klasyczne podejście" to zła praktyka, podobnie jak podejście 'array = ($ (...)); oba na przykład zastąpią pojedynczy token '*' w twoim pliku wejściowym listą plików w bieżącym katalogu. Zobacz [Nie czytaj linii z tekstem] (http://mywiki.wooledge.org/DontReadLinesWithFor), [BashPitfalls # 50] (http://mywiki.wooledge.org/BashPitfalls#hosts.3D.28_.24.28aws_ ... 29_.29) i [BashFAQ # 1] (http://mywiki.wooledge.org/BashFAQ/001) –
Potrzebujesz podziału na słowa dla tego konkretnego przykładu, a nazwa maszyny wirtualnej pasująca do wzorca globu wydaje się mało prawdopodobna. – Mat
Najgorsze zdarzenie utraty danych, w którym się pojawiłem, miało miejsce, ponieważ ktoś zignorował zdarzenie "niemożliwe" (program tworzący pliki "nigdy nie mógł" stworzyć niczego nie pasującego [0-9a-f] {24}; błąd w bibliotece innej firmy uszkodził wskaźnik, wyrzucając losowe śmieci, które zdarzyły się zawierać "*" otoczony spacją do bufora używanego dla nazwy ... i skryptu powłoki iterującego po nazwach plików w celu starzenia się z systemu zapasowego, a następnie usuniętego *wszystko*). –