В чем разница между использованием _<
и <
для stdin при использовании подстановки процесса. Это делается с помощью bash.
Пример:
read bytes _< <(du -bcm random_iso.iso | tail -1); echo $bytes
решение1
Это не _<
оператор, это _
аргумент для передачи в read и <
оператор перенаправления. <(cmd)
Сам по себе он является подстановкой процесса (которая расширяется до имени файла, указывающего на канал).
Что это делает, так это запускает:
read bytes _ < /proc/self/fd/x
Где fd x — это считывающий конец трубы.
На другом (пишущем) конце канала выполняется фоновый процесс подоболочки, du -bcm random_iso.iso | tail -1
и его стандартный вывод перенаправляется в этот канал.
Таким образом, read
в $bytes
переменной будет сохранено первое слово последней строки вывода du -bcm
, а оставшаяся часть строки — в $_
переменной.
Теперь я не знаю, где это du -bcm
имеет смысл. Ни один из параметров -b
, -c
или не является стандартным. While довольно распространен и используется для указания совокупного размера, в GNU , чтобы получить размер файла (не использование диска) в байтах, while округляет размер до следующего мебибайта, так что они будут конфликтующими параметрами (хотя, возможно, они использовались из-за побочного эффекта включения ). У FreeBSD du есть (для мебибайтов), нет , у Solaris нет ни того, ни другого...-m
-c
du
-b
-m
-b
--apparent-size
-m
-b
Похоже, это был замысловатый способ написать:
wc -c < random_iso.iso
Или:
du --apparent-size -cm random_iso.iso | awk 'END{print $1}'
Если они действительно хотели округлить размер файла до следующего мебибайта в системе GNU.
решение2
Как уже упоминалось, _<
не является перенаправлением. Это передается _
как последний аргумент в read
. <
Затем интерпретируется как отдельный оператор перенаправления, перенаправляющий вывод подстановки процесса на stdin.
В скриптах Bash стало общепринятым использовать _
в качестве «отбрасываемой переменной» вместе со read
встроенной. В bash _
— это специальная переменная, которая устанавливается в качестве последнего аргумента команды после выполнения каждой команды. В этом случае это означает, что bytes
будет назначено первое поле, а остальные поля будут отброшены в _
переменную, вместо назначения всех оставшихся полей в bytes
.
Хотя это и условность, есть ряд веских причин избегать _
подобных злоупотреблений.
- Это поведение
_
не определено POSIX. Большинство оболочек не будут делать с ним ничего особенного. - В имеет атрибут , и его использование приведет к тому,
zsh
что оболочка выдаст ошибку._
readonly
- В
mksh
,_
имеет поведение bash только в интерактивном режиме. В неинтерактивном скрипте_
используется для другой цели и не назначается ничего после каждой команды. - в
ksh93
,_
устанавливается только на последний аргумент последней команды в строке. Команды должны физически располагаться на отдельных строках кода, чтобы использовать_
. Кроме того,_
в ksh93 перегружен для использования во многих других контекстах, поэтому назначение для_
этой цели не рекомендуется и будет выполнять разные действия в зависимости от контекста.
Я рекомендую ставить пробел перед перенаправлением, чтобы было понятнее. Я поместил несколько рекомендаций по хорошему стилю перенаправления вЭта статья.