У меня была аналогичная проблема, и выяснилось, что вся проблема такого характера может быть решена следующим образом:
, и таким образом вы сможете стилизовать свои текущие предыдущие элементы (все элементы переопределены текущими и следующими элементами) и ваши следующие элементы.
пример:
/* all items (will be styled as previous) */
li {
color: blue;
}
/* the item i want to distinguish */
li.milk {
color: red;
}
/* next items */
li ~ li {
color: green;
}
<ul>
<li>Tea</li>
<li class="milk">Milk</li>
<li>Juice</li>
<li>others</li>
</ul>
Надеюсь, что это кому-то поможет.
После проведения некоторого времени вчера, пытаясь перенаправить stdout
к stdin
, я закончил со следующим методом. Это не действительно хорошо, но я думаю, что предпочитаю его по именованному каналу / первым прибыл, первым обслужен решение.
read | { P0 | ... | P(n-1); } >/dev/fd/0
Эти { ... } >/dev/fd/0
должен перенаправить stdout к stdin для последовательности канала в целом (т.е. это перенаправляет вывод P (n-1) к входу P0). Используя >&0
или что-то подобное не работает; это, вероятно, потому что удар принимает 0
, только для чтения, в то время как он не возражает писать в /dev/fd/0
.
начальная буква read
- канал необходим, потому что без него оба входной и выходной дескриптор файла является тем же pts устройством (по крайней мере, в моей системе), и перенаправление не имеет никакого эффекта. (pts устройство не работает каналом; запись в него помещает вещи на Ваш экран.) Путем создания входа { ... }
нормальный канал, перенаправление имеет желаемый эффект.
Для иллюстрирования с моим calc
/ square
пример:
function calc() {
# calculate sum of squares of numbers 0,..,10
sum=0
for ((i=0; i<10; i++)); do
echo $i # "request" the square of i
read ii # read the square of i
echo "got $ii" >&2 # debug message
let sum=$sum+$ii
done
echo "sum $sum" >&2 # output result to stderr
}
function square() {
# square numbers
read j # receive first "request"
while [ "$j" != "" ]; do
let jj=$j*$j
echo "square($j) = $jj" >&2 # debug message
echo $jj # send square
read j # receive next "request"
done
}
read | { calc | square; } >/dev/fd/0
Выполнение вышеупомянутый код дает следующий вывод:
square(0) = 0
got 0
square(1) = 1
got 1
square(2) = 4
got 4
square(3) = 9
got 9
square(4) = 16
got 16
square(5) = 25
got 25
square(6) = 36
got 36
square(7) = 49
got 49
square(8) = 64
got 64
square(9) = 81
got 81
sum 285
, Конечно, этот метод - довольно мало взлом. Особенно read
часть имеет нежелательный побочный эффект: завершение "реального" цикла канала не приводит к завершению целого. Я ни о чем не мог думать лучше, чем [1 114], поскольку кажется, что можно только решить, что цикл канала завершился попыткой к записи, пишут что-то в него.
Именованный канал мог бы сделать это:
$ mkfifo outside
$ <outside calc | square >outside &
$ echo "1" >outside ## Trigger the loop to start
Это - очень интересный вопрос. Я (неопределенно) помню присвоение, очень похожее в колледже 17 лет назад. Мы должны были создать массив каналов, где наш код получит дескрипторы файлов для ввода/вывода каждого канала. Тогда код разветвил бы и закрыл бы неиспользованные дескрипторы файлов.
я думаю, что Вы могли сделать что-то похожее с именованными каналами в ударе. Используйте mknod или mkfifo для создания ряда каналов с уникальными именами, на которые можно сослаться, тогда разветвляют программу.
Именованные каналы.
Создают серию fifos, с помощью mkfifo
, т.е. fifo0, fifo1
Тогда присоединяет каждый процесс в термине к каналам, которые Вы хотите:
processn < первым прибыл, первым обслужен (n-1)> fifon
Я сомневаюсь, что sh/bash может сделать это. ZSH был бы лучшей ставкой с ее MULTIOS и coproc функциями.
Стопка команды может быть составлена как строка из массива произвольных команд и оценена с оценкой. Следующий пример дает результат 65536.
function square ()
{
read n
echo $((n*n))
} # ---------- end of function square ----------
declare -a commands=( 'echo 4' 'square' 'square' 'square' )
#-------------------------------------------------------------------------------
# build the command stack using pipes
#-------------------------------------------------------------------------------
declare stack=${commands[0]}
for (( COUNTER=1; COUNTER<${#commands[@]}; COUNTER++ )); do
stack="${stack} | ${commands[${COUNTER}]}"
done
#-------------------------------------------------------------------------------
# run the command stack
#-------------------------------------------------------------------------------
eval "$stack"