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
หัวเปิด 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
เปิดฟีดecho
และลูปถูกยกเลิกการปิดกั้นดังนั้นจึงecho
สามารถเรียกใช้ได้มากขึ้นตามเวลาที่cat
อ่านเนื้อหาและปิดไพพ์ (ทำให้ถัดecho
จากอินสแตนซ์ของไพพ์ใหม่)
การหลีกเลี่ยงอาจเพิ่มความล่าช้าเช่นโดยการเรียกใช้ภายนอกecho
ตามที่แนะนำโดย @jimmij หรือเพิ่มบางอย่างsleep
แต่ก็ยังไม่สมบูรณ์มากหรือคุณสามารถสร้างไปป์ที่มีชื่อหลังจากแต่ละ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
) &
ด้วยวิธีนี้ปัญหาเดียวคือถ้าคุณเรียกใช้แมวหลายตัวในเวลาเดียวกัน (พวกมันทั้งหมดเปิดฟีฟ่าก่อนที่ลูปการเขียนของเราจะพร้อมสำหรับเปิดการเขียน) ซึ่งในกรณีนี้พวกเขาจะแบ่งปันecho
เอาต์พุต
ฉันจะแนะนำไม่ให้สร้างชื่อคงที่โลกที่สามารถอ่านได้ (หรือไฟล์ใด ๆ สำหรับเรื่องนั้น) ในไดเรกทอรีที่เขียนได้ทั่วโลกเช่น/tmp
ถ้าไม่มีบริการที่จะเปิดเผยต่อผู้ใช้ทุกคนในระบบ