Ваша ошибка в том, что вы создали две отдельные файловые системы BTRFS. Вы можете увидеть в выводе sudo btrfs fi
две файловые системы, каждая с одним устройством.
Чтобы исправить это, используйте команду btrfs device add
, чтобы добавить новый диск в существующую файловую систему. ТОГДА сделайте ребаланс.
https://btrfs.wiki.kernel.org/index.php/Manpage/btrfs-device
В большинстве случаев будет много проблем из-за того, как работает буферизация stdio. Обходной путь для Linux может состоять в том, чтобы использовать программу stdbuf
и запустить команду с помощью coproc, чтобы вы могли явно управлять чередованием вывода.
Далее предполагается, что команда будет выводить одну строку после каждой строки ввода.
#!/bin/bash
coproc stdbuf -i0 -o0 "$@"
IFS=
while read -r in ; do
printf "%s " "$in"
printf "%s\n" "$in" >&${COPROC[1]}
read -r out <&${COPROC[0]}
printf "%s\n" "$out"
done
Если требуется более общее решение, так как OP требует только каждой строки ввода в программу, чтобы в конечном итоге вывести одну строку, а не немедленно, тогда необходим более сложный подход. Создайте цикл событий, используя read -t 0
, чтобы попытаться прочитать из стандартного ввода и процесса co -, если у вас есть один и тот же «номер строки» для обоих, затем выведите, в противном случае сохраните строку. Чтобы избежать использования 100% процессора, если в любом раунде цикла событий ни один из них не был готов, введите небольшую задержку перед повторным запуском цикла событий. Существуют дополнительные сложности, если процесс выводит неполные строки, их необходимо буферизовать.
Если необходимо это более общее решение, я бы написал его, используя expect , так как оно уже имеет хорошую поддержку обработки сопоставления шаблонов для нескольких входных потоков. Однако это не решение для bash/zsh.
Функция оболочки. Это будет работать в любой оболочке, которая поддерживает строки <<<
здесь -, включая zsh и bash.
xyz() {
while read line
do
printf "%s " "$line"
"$@" <<<"$line"
done
}
$ (echo "foo"; echo "bar") | xyz rev
foo oof
bar rab
В данном конкретном случае я бы использовалperl
:
printf '%s\n' foo bar | perl -Mopen=locale -lpe '$_.= " ". reverse$_'
foo oof
bar rab
Который вы можете расширить для работы с графемными кластерами:
$ printf '%s\n' $'complique\u301' |
perl -Mopen=locale -lpe '$_.= " ". join "", reverse/\X/g'
compliqué éuqilpmoc
илиzsh
:
while IFS= read -r line; do
print -r -- $line ${(j::)${(s::Oa)line}}
done
Хотя я бы не стал использовать while read
циклы для обработки текста , даже вzsh
(даже если в данном конкретном случае это не так уж плохо, поскольку используются только встроенные команды ).
В общем случае использование временных файлов, вероятно, является лучшим подходом. С zsh
,вы можете сделать это с помощью:
(){paste -d ' ' $1 <(rev <$1)} =(print -l foo bar)
(, где =(...)
создает и очищает временный файл ).
Замена его конвейерами и некоторой формой tee
ing — это рецепт тупиковой ситуации в общем случае. См. эти похожие вопросы для некоторых подходов и подробностей о тупиковых ситуациях:
Это gawk
реализация со -процессного подхода , описанного icarus и, следовательно, с учетом тех же соображений буферизации stdio, см. также это
{ echo foo; echo bar; } | gawk -vcmd=rev '
BEGIN {c=sprintf("stdbuf -i0 -o0 \"%s\"", cmd)}
{
printf "%s ", $0
print |& c; fflush()
c |& getline
print
}'
foo oof
bar rab
Именованные каналы спешат на помощь!
xyz() {
pipe="/tmp/$$pipe"
mkfifo "$pipe"
tee "$pipe" | "$@" | paste "$pipe" -
rm "$pipe"
}
Результаты вашего примера команды:
$ (echo "foo"; echo "bar") | xyz rev
foo oof
bar rab
Приведенная выше функция делает именно то, что вы описываете.