Из серии «я познаю мир».
Ковыряясь в инит-скриптах замшелого Линукса, установленного на моём NAS, встретил следующую строку
read line <"$pid_file"
Вроде бы очевидная конструкция резанула глаз своей непривычностью. Первой мыслью было — зачем же так выражаться, ведь
line=$(cat "$pid_file")
выглядит куда нагляднее (не то, что башизм $(<"$pid_file")
). Но, приведя пульс в порядок и отогнав приступ праведного гнева, я стал размышлять над этой строчкой:
- не порождаются суб-шелл и cat (минус два форка)
- читается почти как well-written prose (если не считать косяк в виде имени line для переменной, содержащей pid)
- надо брать на вооружение
Беглый анализ показывает, что в современном Дебиане оба подхода примерно одинаково популярны:
$ grep '=$(cat [^)]*)' -r /etc/ 2>/dev/null | wc -l
10
$ egrep 'read [[:alpha:]_][[:alnum:]_]*[[:blank:]]*<' -r /etc/ 2>/dev/null | wc -l
7
Что скажут ценители?
Ну, и для развлечения тест производительности :-)
Классика:
$ cat cat_test.sh
#!/bin/sh
i=0
while [ $i -lt $1 ]; do
var=$(cat value)
i=$(($i+1))
done
echo $var
Башизм:
$ cat bashcat_test.sh
#!/bin/bash
i=0
while [ $i -lt $1 ]; do
var=$(< value)
i=$(($i+1))
done
echo $var
read:
$ cat read_test.sh
#!/bin/sh
i=0
while [ $i -lt $1 ]; do
read var < value
i=$(($i+1))
done
echo $var
Результаты:
$ echo this is a value > value
$ time ./cat_test.sh 1000
this is a value
real 0m2.129s
user 0m0.056s
sys 0m0.212s
$ time ./bashcat_test.sh 1000
this is a value
real 0m0.777s
user 0m0.108s
sys 0m0.144s
$ time ./read_test.sh 1000
this is a value
real 0m0.036s
user 0m0.000s
sys 0m0.036s