ksh93
имеет дисциплины, которые обычно используются для такого рода вещей. С помощью zsh
вы можете захватить динамически именованный каталог функцию :
Определите, например:
zsh_directory_name() {
case $1 in
(n)
case $2 in
(incr) reply=($((++incr)))
esac
esac
}
А затем вы можете использовать ~ [incr]
, чтобы каждый раз получать увеличиваемый $ incr
:
$ echo ~[incr]
1
$ echo ~[incr] ~[incr]
2 3
Ваш подход не работает, потому что в head -1 / tmp / ints
head открывает fifo, считывает полный буфер, печатает одна строка, , а затем закрывает ее . После закрытия пишущий конец видит сломанную трубу.
Вместо этого вы можете сделать следующее:
$ fifo=~/.generators/incr
$ (umask 077 && mkdir -p $fifo:h && rm -f $fifo && mkfifo $fifo)
$ seq infinity > $fifo &
$ exec 3< $fifo
$ IFS= read -rneu3
1
$ IFS= read -rneu3
2
Здесь мы оставляем конец чтения открытым на fd 3, и read
считывает по одному байту за раз, а не полный буфер, чтобы гарантировать точное чтение одна строка (до символа новой строки).
Или вы могли бы сделать:
$ fifo=~/.generators/incr
$ (umask 077 && mkdir -p $fifo:h && rm -f $fifo && mkfifo $fifo)
$ while true; do echo $((++incr)) > $fifo; done &
$ cat $fifo
1
$ cat $fifo
2
На этот раз мы создаем экземпляр канала для каждого значения.Это позволяет возвращать данные, содержащие произвольное количество строк.
Однако в этом случае, как только cat
откроет fifo, echo
и цикл будут разблокированы, поэтому может быть запущено еще echo
, к тому времени, когда cat
прочитает содержимое и закроет канал (заставляя следующее эхо
создать экземпляр нового канала).
Чтобы обойти эту проблему, можно было бы добавить некоторую задержку, например, запустив внешнее эхо
, как предлагает @jimmij, или добавить немного сна
, но это все равно было бы не очень надежный, или вы можете воссоздавать именованный канал после каждого echo
:
while
mkfifo $fifo &&
echo $((++incr)) > $fifo &&
rm -f $fifo
do : nothing
done &
При этом остаются короткие окна, в которых канал не существует (между unlink ()
, выполненным ] rm
и mknod ()
от mkfifo
), вызывающих сбой cat
, и очень короткие окна, в которых канал был создан, но не процесс когда-либо снова напишет в него (между write ()
и close ()
, выполненным echo
), в результате чего cat
ничего не вернет и короткие окна, в которых именованный канал все еще существует, но ничто никогда не откроет его для записи (между close ()
, выполненным echo
, и unlink ()
сделал rm
), где будет висеть cat
.
Вы можете удалить некоторые из этих окон , выполнив следующие действия:
fifo=~/.generators/incr
(
umask 077
mkdir -p $fifo:h && rm -f $fifo && mkfifo $fifo &&
while
mkfifo $fifo.new &&
{
mv $fifo.new $fifo &&
echo $((++incr))
} > $fifo
do : nothing
done
) &
Таким образом, единственная проблема будет в том, если вы запустите несколько cat одновременно (все они открывают FIFO перед нашим циклом записи готов открыть его для записи), и в этом случае они поделятся выводом echo
.
Я бы также посоветовал не создавать фиксированные имена, всемирно читаемые fifos (или любые файлы, если это имеет значение) в всемирно доступных для записи каталогах, таких как / tmp
, если только это не сервис, доступный всем пользователям в системе.
Хорошо, я нашел решение своей проблемы. Программа Sipcmd имеет следующую особенность:
-o --opallog enable extra opal library logging to file
Итак, я изменил свой cronjob на это:
0 8,14,20 * * * /usr/bin/sipcmd -o ~/call.log -P sip -u abc -c cba -w 192.168.8.10 -x "c010101010101;ws45000;h"
Теперь с существующим файлом журнала я мог бы использовать функцию, которая ищет код состояния SIP, который сообщает мне, прошел ли вызов (или нет ).
Вот коды состояния SIP,если кому интересно:
https://de.wikipedia.org/wiki/SIP-Status-Codes
Успехов всем.