tail -f失效原因(vim修改文件)

本文分析了tail-f命令在文件inode发生变化时失效的原因,探讨了vim编辑器操作对tail-f的影响,并提供了解决方案,即使用tail-F命令进行有效追踪。

tail -f 失效的情况分析

im是将原来的文件删除后,然后再生成一个新的文件,而tail -f命令是根据文件的inode来追踪文件的,vim把原来的文件删除,新生成的同名文件的inode已经发生了变化,所以导致tail -f命令失效。

而echo 123 >> a.txt是可以生效的

结论:tail -f通过inode追踪文件,如果文件的inode发生了变化,将会使tail -f失效。

解决方案:
使用tail -F替代tail -f,根据man tail的说明,tail -F在文件不可以打开的时候,会重试打开该文件,也就是在vim删除旧文件,创建新文件的过程中,tail短暂性失去了对tmp.test文件的访问权限,加上-F选项后,tail在文件恢复访问后可以重新对文件实施跟踪。

[root@yfw ~]# cd /opt/openfire/bin [root@yfw bin]# #!/bin/bash [root@yfw bin]# [root@yfw bin]# # ============================================= [root@yfw bin]# # OpenFire 启动脚本 - 生产安全版 (systemd 兼容) [root@yfw bin]# # 使用 Java 17 绝对路径,避免软链接失效 [root@yfw bin]# # ============================================= [root@yfw bin]# [root@yfw bin]# # --- 显式设置 JAVA_HOME 为真实路径 --- [root@yfw bin]# export JAVA_HOME="/usr/lib/jvm/java-17-openjdk-17.0.1.0.12-2.el8_5.x86_64" [root@yfw bin]# export OPENFIRE_HOME="/opt/openfire" [root@yfw bin]# [root@yfw bin]# # --- 强制使用绝对路径调用 Java --- [root@yfw bin]# JAVA_EXEC="$JAVA_HOME/bin/java" [root@yfw bin]# [root@yfw bin]# # --- 日志与 PID 路径 --- [root@yfw bin]# LOG_DIR="$OPENFIRE_HOME/logs" [root@yfw bin]# LOG_FILE="$LOG_DIR/nohup.out" [root@yfw bin]# PID_FILE="$LOG_DIR/openfire.pid" [root@yfw bin]# [root@yfw bin]# # --- 切换到 OpenFire 主目录 --- [root@yfw bin]# cd "$OPENFIRE_HOME" || { > echo "ERROR: Cannot access $OPENFIRE_HOME" >&2 > exit 1 > } [root@yfw openfire]# [root@yfw openfire]# # --- 创建日志目录(如果不存在)--- [root@yfw openfire]# if [ ! -d "$LOG_DIR" ]; then > mkdir -p "$LOG_DIR" || { > echo "ERROR: Cannot create log directory: $LOG_DIR" >&2 > exit 1 > } > fi [root@yfw openfire]# [root@yfw openfire]# # --- 检查 Java 是否存在且可执行 --- [root@yfw openfire]# if [ ! -x "$JAVA_EXEC" ]; then > echo "ERROR: Java executable not found or not executable: $JAVA_EXEC" >&2 > ls -la "$JAVA_HOME/bin/" >&2 || echo "Cannot list JAVA_HOME/bin" >&2 > exit 1 > fi [root@yfw openfire]# [root@yfw openfire]# # --- 构建 Classpath --- [root@yfw openfire]# CLASSPATH="$OPENFIRE_HOME/resources:$OPENFIRE_HOME/lib/*" [root@yfw openfire]# [root@yfw openfire]# # --- JVM 参数 --- [root@yfw openfire]# JAVA_OPTS="-server -Xms64m -Xmx512m -DopenfireHome=$OPENFIRE_HOME -Djava.ext.dirs=$JAVA_HOME/lib/ext:$OPENFIRE_HOME/lib" [root@yfw openfire]# [root@yfw openfire]# # --- 检查是否有旧进程 --- [root@yfw openfire]# if [ -f "$PID_FILE" ]; then > OLD_PID=$(cat "$PID_FILE" 2>/dev/null) > if [ -n "$OLD_PID" ] && kill -0 "$OLD_PID" 2>/dev/null; then > echo "ERROR: OpenFire already running as PID $OLD_PID" >&2 > exit 1 > else > rm -f "$PID_FILE" > fi > fi [root@yfw openfire]# [root@yfw openfire]# # --- 启动 OpenFire --- [root@yfw openfire]# nohup "$JAVA_EXEC" $JAVA_OPTS -cp "$CLASSPATH" org.jivesoftware.openfire.starter.Starter >"$LOG_FILE" 2>&1 & [1] 1157015 [root@yfw openfire]# [root@yfw openfire]# # --- 获取后台进程 PID --- [root@yfw openfire]# OPENFIRE_PID=$! [root@yfw openfire]# [root@yfw openfire]# # --- 写入 PID 文件 --- [root@yfw openfire]# echo $OPENFIRE_PID > "$PID_FILE" [root@yfw openfire]# if [ $? -ne 0 ]; then > echo "ERROR: Failed to write PID file: $PID_FILE" >&2 > kill "$OPENFIRE_PID" 2>/dev/null || true > exit 1 > fi [root@yfw openfire]# chmod 644 "$PID_FILE" [root@yfw openfire]# [root@yfw openfire]# # --- 输出成功信息 --- [root@yfw openfire]# echo "OpenFire started (PID $OPENFIRE_PID)" OpenFire started (PID 1157015) [root@yfw openfire]# echo "Log: tail -f $LOG_FILE" Log: tail -f /opt/openfire/logs/nohup.out [root@yfw openfire]# [root@yfw openfire]# exit 0 logout 连接已断开,按回车将尝试重新连接! 正在尝试重新连接! Welcome to Huawei Cloud Service Last login: Sat Nov 15 14:36:53 2025 from 127.0.0.1 ✅ JAVA_HOME: /usr/lib/jvm/java-11-openjdk ✅ Maven home: /opt/maven ✅ Java version: openjdk version "11.0.13" 2021-10-19 LTS [root@yfw ~]# #!/bin/bash [root@yfw ~]# [root@yfw ~]# # ============================================= [root@yfw ~]# # OpenFire 启动脚本 - 生产安全版 (systemd 兼容) [root@yfw ~]# # 使用 Java 17 绝对路径,避免软链接失效 [root@yfw ~]# # ============================================= [root@yfw ~]# [root@yfw ~]# # --- 显式设置 JAVA_HOME 为真实路径 --- [root@yfw ~]# export JAVA_HOME="/usr/lib/jvm/java-17-openjdk-17.0.1.0.12-2.el8_5.x86_64" [root@yfw ~]# export OPENFIRE_HOME="/opt/openfire" [root@yfw ~]# [root@yfw ~]# # --- 强制使用绝对路径调用 Java --- [root@yfw ~]# JAVA_EXEC="$JAVA_HOME/bin/java" [root@yfw ~]# [root@yfw ~]# # --- 日志与 PID 路径 --- [root@yfw ~]# LOG_DIR="$OPENFIRE_HOME/logs" [root@yfw ~]# LOG_FILE="$LOG_DIR/nohup.out" [root@yfw ~]# PID_FILE="$LOG_DIR/openfire.pid" [root@yfw ~]# [root@yfw ~]# # --- 切换到 OpenFire 主目录 --- [root@yfw ~]# cd "$OPENFIRE_HOME" || { > echo "ERROR: Cannot access $OPENFIRE_HOME" >&2 > exit 1 > } [root@yfw openfire]# [root@yfw openfire]# # --- 创建日志目录(如果不存在)--- [root@yfw openfire]# if [ ! -d "$LOG_DIR" ]; then > mkdir -p "$LOG_DIR" || { > echo "ERROR: Cannot create log directory: $LOG_DIR" >&2 > exit 1 > } > fi [root@yfw openfire]# [root@yfw openfire]# # --- 检查 Java 是否存在且可执行 --- [root@yfw openfire]# if [ ! -x "$JAVA_EXEC" ]; then > echo "ERROR: Java executable not found or not executable: $JAVA_EXEC" >&2 > ls -la "$JAVA_HOME/bin/" >&2 || echo "Cannot list JAVA_HOME/bin" >&2 > exit 1 > fi [root@yfw openfire]# [root@yfw openfire]# # --- 构建 Classpath --- [root@yfw openfire]# CLASSPATH="$OPENFIRE_HOME/resources:$OPENFIRE_HOME/lib/*" [root@yfw openfire]# [root@yfw openfire]# # --- JVM 参数 --- rs=$JAVA_HOME/lib/ext:$OPENFIRE_HOME/lib"Xms64m -Xmx512m -DopenfireHome=$OPENFIRE_HOME -Djava.ext.dir [root@yfw openfire]# [root@yfw openfire]# # --- 检查是否有旧进程 --- [root@yfw openfire]# if [ -f "$PID_FILE" ]; then > OLD_PID=$(cat "$PID_FILE" 2>/dev/null) > if [ -n "$OLD_PID" ] && kill -0 "$OLD_PID" 2>/dev/null; then > echo "ERROR: OpenFire already running as PID $OLD_PID" >&2 > exit 1 > else > rm -f "$PID_FILE" > fi > fi [root@yfw openfire]# [root@yfw openfire]# # --- 启动 OpenFire --- r.Starter >"$LOG_FILE" 2>&1 &JAVA_EXEC" $JAVA_OPTS -cp "$CLASSPATH" org.jivesoftware.openfire.starter [1] 1157663 [root@yfw openfire]# [root@yfw openfire]# # --- 获取后台进程 PID --- [root@yfw openfire]# OPENFIRE_PID=$! [root@yfw openfire]# [root@yfw openfire]# # --- 写入 PID 文件 --- [root@yfw openfire]# echo $OPENFIRE_PID > "$PID_FILE" [root@yfw openfire]# if [ $? -ne 0 ]; then > echo "ERROR: Failed to write PID file: $PID_FILE" >&2 > kill "$OPENFIRE_PID" 2>/dev/null || true > exit 1 > fi [root@yfw openfire]# chmod 644 "$PID_FILE" [root@yfw openfire]# [root@yfw openfire]# # --- 输出成功信息 --- [root@yfw openfire]# echo "OpenFire started (PID $OPENFIRE_PID)" OpenFire started (PID 1157663) [root@yfw openfire]# echo "Log: tail -f $LOG_FILE" Log: tail -f /opt/openfire/logs/nohup.out [root@yfw openfire]# [root@yfw openfire]# exit 0 logout 连接已断开,按回车将尝试重新连接! 正在尝试重新连接! Welcome to Huawei Cloud Service Last login: Sat Nov 15 14:37:00 2025 from 127.0.0.1 ✅ JAVA_HOME: /usr/lib/jvm/java-11-openjdk ✅ Maven home: /opt/maven ✅ Java version: openjdk version "11.0.13" 2021-10-19 LTS [root@yfw ~]# ps aux | grep openfire root 1156241 4.3 4.8 3639516 184364 ? Sl 14:36 0:04 /usr/lib/jvm/java-17-openjdk-17.0.1.0.12-2.el8_5.x86_64/bin/java -server -DopenfireHome=/opt/openfire -Dopenfire.lib.dir=/opt/openfire/lib -classpath /opt/openfire/lib/startup.jar org.jivesoftware.openfire.starter.ServerStarter root 1158357 0.0 0.0 12136 1124 pts/0 S+ 14:37 0:00 grep --color=auto openfire [root@yfw ~]# tail -f /opt/openfire/logs/nohup.out -Djava.ext.dirs=/usr/lib/jvm/java-17-openjdk-17.0.1.0.12-2.el8_5.x86_64/lib/ext:/opt/openfire/lib is not supported. Use -classpath instead. Error: Could not create the Java Virtual Machine. Error: A fatal exception has occurred. Program will exit. tail: /opt/openfire/logs/nohup.out: file truncated -Djava.ext.dirs=/usr/lib/jvm/java-17-openjdk-17.0.1.0.12-2.el8_5.x86_64/lib/ext:/opt/openfire/lib is not supported. Use -classpath instead. Error: Could not create the Java Virtual Machine. Error: A fatal exception has occurred. Program will exit. tail: /opt/openfire/logs/nohup.out: file truncated -Djava.ext.dirs=/usr/lib/jvm/java-17-openjdk-17.0.1.0.12-2.el8_5.x86_64/lib/ext:/opt/openfire/lib is not supported. Use -classpath instead. Error: Could not create the Java Virtual Machine. Error: A fatal exception has occurred. Program will exit.
最新发布
11-16
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值