本文目录导读:

我来介绍几种在Shell脚本中实现环形缓冲区的方法:
方法1:使用数组实现(Bash 4.0+)
#!/bin/bash
# 环形缓冲区实现
declare -a buffer=()
buffer_size=5
head=0
tail=0
count=0
# 初始化缓冲区
init_buffer() {
buffer=()
for ((i=0; i<buffer_size; i++)); do
buffer[$i]=""
done
head=0
tail=0
count=0
}
# 写入数据
write_buffer() {
local data="$1"
if [ $count -eq $buffer_size ]; then
echo "Buffer full, overwriting oldest data"
head=$(( (head + 1) % buffer_size ))
else
count=$((count + 1))
fi
buffer[$tail]="$data"
tail=$(( (tail + 1) % buffer_size ))
}
# 读取数据
read_buffer() {
if [ $count -eq 0 ]; then
echo "Buffer empty"
return 1
fi
local data="${buffer[$head]}"
buffer[$head]=""
head=$(( (head + 1) % buffer_size ))
count=$((count - 1))
echo "$data"
}
# 查看缓冲区内容
show_buffer() {
echo "Buffer contents:"
local idx=$head
for ((i=0; i<count; i++)); do
echo "[$(( (idx + i) % buffer_size ))]: ${buffer[$(( (idx + i) % buffer_size ))]}"
done
}
# 测试
init_buffer
# 写入测试数据
for i in {1..7}; do
write_buffer "Data_$i"
echo "Wrote: Data_$i"
done
show_buffer
echo -e "\nReading data:"
while read_buffer 2>/dev/null; do
:
done
方法2:使用文件实现(更通用)
#!/bin/bash
# 基于文件的环形缓冲区
BUFFER_DIR="/tmp/ring_buffer_$$"
BUFFER_SIZE=5
counter=0
# 初始化缓冲区
init_file_buffer() {
mkdir -p "$BUFFER_DIR"
echo 0 > "$BUFFER_DIR/head"
echo 0 > "$BUFFER_DIR/tail"
echo 0 > "$BUFFER_DIR/count"
for ((i=0; i<BUFFER_SIZE; i++)); do
: > "$BUFFER_DIR/$i"
done
}
# 写入数据
write_file_buffer() {
local data="$1"
local count=$(cat "$BUFFER_DIR/count")
local tail=$(cat "$BUFFER_DIR/tail")
if [ "$count" -eq "$BUFFER_SIZE" ]; then
local head=$(cat "$BUFFER_DIR/head")
head=$(( (head + 1) % BUFFER_SIZE ))
echo "$head" > "$BUFFER_DIR/head"
else
count=$((count + 1))
echo "$count" > "$BUFFER_DIR/count"
fi
echo "$data" > "$BUFFER_DIR/$tail"
tail=$(( (tail + 1) % BUFFER_SIZE ))
echo "$tail" > "$BUFFER_DIR/tail"
}
# 读取数据
read_file_buffer() {
local count=$(cat "$BUFFER_DIR/count")
if [ "$count" -eq 0 ]; then
echo "Buffer empty"
return 1
fi
local head=$(cat "$BUFFER_DIR/head")
local data=$(cat "$BUFFER_DIR/$head")
: > "$BUFFER_DIR/$head"
head=$(( (head + 1) % BUFFER_SIZE ))
echo "$head" > "$BUFFER_DIR/head"
count=$((count - 1))
echo "$count" > "$BUFFER_DIR/count"
echo "$data"
}
# 清理
cleanup_file_buffer() {
rm -rf "$BUFFER_DIR"
}
# 测试
init_file_buffer
# 写入测试数据
for i in {1..7}; do
write_file_buffer "File_Data_$i"
echo "Wrote: File_Data_$i"
done
echo -e "\nReading file buffer:"
while read_file_buffer 2>/dev/null; do
:
done
cleanup_file_buffer
方法3:使用命名管道实现(FIFO)
#!/bin/bash
# 使用命名管道实现环形缓冲区
PIPE_NAME="/tmp/ring_pipe"
BUFFER_SIZE=5
# 创建命名管道
init_pipe_buffer() {
if [ ! -p "$PIPE_NAME" ]; then
mkfifo "$PIPE_NAME"
fi
# 后台进程管理缓冲区
(
declare -a buffer=()
local head=0
local tail=0
local count=0
while true; do
if read line; then
# 解析指令
case "$line" in
WRITE:*)
data="${line#WRITE:}"
if [ $count -eq $BUFFER_SIZE ]; then
head=$(( (head + 1) % BUFFER_SIZE ))
else
count=$((count + 1))
fi
buffer[$tail]="$data"
tail=$(( (tail + 1) % BUFFER_SIZE ))
echo "OK" >&3
;;
READ)
if [ $count -gt 0 ]; then
data="${buffer[$head]}"
head=$(( (head + 1) % BUFFER_SIZE ))
count=$((count - 1))
echo "$data" >&3
else
echo "EMPTY" >&3
fi
;;
SHOW)
echo "Buffer[${#buffer[@]}] count=$count" >&3
;;
QUIT)
break
;;
esac
fi
done
) < "$PIPE_NAME" 3>&1 &
BUFFER_PID=$!
}
# 写入数据
write_pipe_buffer() {
echo "WRITE:$1" > "$PIPE_NAME"
read response < "$PIPE_NAME"
echo "Write response: $response"
}
# 读取数据
read_pipe_buffer() {
echo "READ" > "$PIPE_NAME"
read data < "$PIPE_NAME"
echo "$data"
}
# 测试
init_pipe_buffer
sleep 0.1 # 等待后台进程启动
# 写入测试数据
for i in {1..7}; do
write_pipe_buffer "Pipe_Data_$i"
done
echo -e "\nReading pipe buffer:"
for ((i=0; i<5; i++)); do
read_pipe_buffer
done
# 清理
echo "QUIT" > "$PIPE_NAME"
kill $BUFFER_PID 2>/dev/null
rm -f "$PIPE_NAME"
方法4:简单Shell数组实现(最实用)
#!/bin/bash
# 简单实用的环形缓冲区
ring_buffer() {
local -n arr=$1
local -n idx=$2
local size=$3
# 添加元素
if [ "$4" = "push" ]; then
arr[$idx]=$5
idx=$(( (idx + 1) % size ))
# 获取所有元素
elif [ "$4" = "get_all" ]; then
for ((i=0; i<${#arr[@]}; i++)); do
if [ -n "${arr[$i]}" ]; then
echo "${arr[$i]}"
fi
done
# 获取最新元素
elif [ "$4" = "get_latest" ]; then
local last=$(( (idx - 1 + size) % size ))
echo "${arr[$last]}"
fi
}
# 使用示例
declare -a buffer=()
current=0
buffer_size=5
# 写入数据
for i in {1..10}; do
ring_buffer buffer current $buffer_size "push" "Log_Entry_$i"
done
echo "Current buffer contents:"
ring_buffer buffer current $buffer_size "get_all"
使用建议
- 数组实现:最简单,适合小型应用
- 文件实现:可持久化,适合进程间通信
- 命名管道:适合实时数据流处理
- 关联数组:可以扩展为更复杂的缓存结构
选择哪种方法取决于你的具体需求:数据量大小、是否需要持久化、是否需要进程间通信等。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播