linux mesg命令

命令简介

mesg 命令用于控制终端是否允许接收其他用户通过writetalk命令发送的消息。在多用户Linux系统中,这个命令可以保护终端不被其他用户的消息干扰,提高工作专注度。

多用户通信:在传统的多用户Unix/Linux环境中,用户可以通过writetalk命令直接向其他用户的终端发送消息。mesg命令用于控制是否允许接收这类消息。

基本语法

# 基本格式
mesg [选项] [y|n]

# 常用格式
mesg            # 显示当前状态
mesg y          # 允许接收消息
mesg n          # 禁止接收消息
mesg -V         # 显示版本信息
mesg -h         # 显示帮助信息

常用选项

选项 描述
y, yes 允许其他用户向终端发送消息
n, no 禁止其他用户向终端发送消息
-v, --verbose 详细模式,显示更多信息
-V, --version 显示版本信息并退出
-h, --help 显示帮助信息并退出

安装和可用性

mesg 是GNU coreutils的一部分,几乎所有Linux发行版都预装了:

# 1. 检查是否已安装
which mesg
mesg --version
# 输出示例:mesg (GNU coreutils) 8.30

# 2. 如果未安装,安装coreutils
# 实际上mesg几乎总是已安装,但如果需要:
# Debian/Ubuntu
sudo apt-get update
sudo apt-get install coreutils

# RHEL/CentOS
sudo yum install coreutils
# 或
sudo dnf install coreutils

# 3. 查看coreutils版本
ls --version | head -1
# 或
cp --version | head -1

# 4. 从源码编译coreutils(不推荐)
wget https://ftp.gnu.org/gnu/coreutils/coreutils-8.32.tar.xz
tar -xf coreutils-8.32.tar.xz
cd coreutils-8.32
./configure
make
sudo make install

# 5. 相关工具包
# 除了coreutils,这些工具也可能包含mesg:
# util-linux: 包含write, wall, mesg等
# bsdutils: BSD工具版本

# 6. 验证安装
mesg
# 应该显示:is y 或 is n

实际示例

示例1:基本消息控制

使用mesg进行基本的消息控制:

# 1. 查看当前消息状态
mesg
# 输出:is y  (允许接收消息)
# 或:is n   (禁止接收消息)

# 2. 允许接收消息
mesg y
# 或
mesg yes
# 输出:is y

# 3. 禁止接收消息
mesg n
# 或
mesg no
# 输出:is n

# 4. 在脚本中检查状态
if mesg | grep -q "is y"; then
    echo "消息接收已启用"
else
    echo "消息接收已禁用"
fi

# 5. 切换状态
# 如果当前是y,切换到n;如果是n,切换到y
mesg $(mesg | awk '{print $2 == "y" ? "n" : "y"}')

# 6. 显示详细信息
mesg -v
# 输出更详细的信息

# 7. 在多个终端中设置
# 为当前tty设置
mesg y
# 查看当前tty
tty
# 输出:/dev/pts/0

# 8. 检查其他用户的终端状态
# 首先查看哪些用户已登录
who
# 输出示例:
# alice   pts/0        2023-10-01 10:00 (192.168.1.100)
# bob     pts/1        2023-10-01 10:05 (192.168.1.101)

# 检查Alice的终端是否允许消息
sudo -u alice mesg
# 注意:需要权限或Alice的登录shell

# 9. 在.bashrc中设置默认值
# 添加到~/.bashrc
echo "mesg n 2>/dev/null || true" >> ~/.bashrc
# 这样每次登录时自动禁用消息

# 10. 临时测试消息
# 终端1:启动消息监听
mesg y
# 等待消息

# 终端2:向终端1发送消息
# 首先查看终端1的tty
# 在终端1中运行:tty
# 假设终端1是/dev/pts/0
write alice pts/0
# 然后输入消息,按Ctrl+D发送

# 11. 批量设置用户
# 为系统所有用户禁用消息(需要root)
for user in $(getent passwd | cut -d: -f1); do
    sudo -u "$user" mesg n 2>/dev/null || true
done

# 12. 检查系统范围的消息策略
# 查看/etc/profile或/etc/bash.bashrc中是否有全局设置
grep -r "mesg" /etc/profile /etc/bash.bashrc /etc/bashrc 2>/dev/null

# 13. 消息状态与tty权限的关系
# mesg实际上修改了tty设备的写权限
ls -l $(tty)
# 启用消息时:crw--w----
# 禁用消息时:crw-------

# 14. 直接修改tty权限(不推荐)
# 启用消息
chmod g+w $(tty)
# 禁用消息
chmod g-w $(tty)

# 15. 在远程会话中保持设置
# SSH连接时,mesg设置不会自动继承
# 可以在~/.bashrc中添加:
if [ -t 0 ]; then
    mesg n
fi

# 16. 调试消息问题
# 详细模式查看发生了什么
mesg -v y
# 可能显示:change mode of /dev/pts/0 to 0620

# 17. 检查coreutils版本
mesg --version
# 输出:mesg (GNU coreutils) 8.30

# 18. 获取帮助
mesg --help
# 显示使用帮助

# 19. 在脚本中安全使用
# 总是检查命令是否成功
if mesg n; then
    echo "消息已禁用"
else
    echo "无法禁用消息" >&2
fi

# 20. 与其他命令结合
# 在运行重要任务时禁用消息
mesg n
# 运行重要脚本
./important_script.sh
# 完成后恢复
mesg y

示例2:write和talk命令使用

配合write和talk命令进行用户间通信:

#!/bin/bash
# write和talk命令使用示例

# 1. 查看在线用户
who
# 输出示例:
# alice   pts/0        2023-10-01 10:00 (192.168.1.100)
# bob     pts/1        2023-10-01 10:05 (192.168.1.101)
# charlie pts/2        2023-10-01 10:10 (192.168.1.102)

# 2. 检查用户的消息状态
check_user_mesg() {
    local user=$1
    local tty=$2

    echo "检查用户 $user 在 $tty 的消息状态:"

    # 尝试检查(需要权限)
    sudo -u "$user" mesg 2>/dev/null || echo "无法检查"
}

# 3. 使用write发送消息
send_message_write() {
    local target_user=$1
    local target_tty=$2
    local message=$3

    echo "向 $target_user ($target_tty) 发送消息: $message"

    # 方法1:直接通过管道
    echo "$message" | write "$target_user" "$target_tty"

    # 方法2:交互式发送
    # write "$target_user" "$target_tty"
    # 然后输入消息,按Ctrl+D结束
}

# 4. 使用talk进行实时聊天
start_talk() {
    local target_user=$1
    local target_host=${2:-localhost}

    echo "启动与 $target_user@$target_host 的talk会话"

    # 启动talk客户端
    talk "$target_user@$target_host"

    # 注意:talk需要双方都运行talkd服务
    # 检查talkd服务
    systemctl status inetd 2>/dev/null || systemctl status xinetd 2>/dev/null
}

# 5. 广播消息给所有用户
broadcast_message() {
    local message=$1

    echo "广播消息: $message"

    # 使用wall命令
    wall <<< "$message"

    # 或使用write给每个用户
    who | while read user tty rest; do
        echo "$message" | write "$user" "$tty" 2>/dev/null
    done
}

# 6. 消息发送工具函数
message_tool() {
    echo "=== 用户消息工具 ==="

    # 显示在线用户
    echo "在线用户:"
    who

    echo ""
    echo "请选择操作:"
    echo "1. 发送write消息"
    echo "2. 启动talk会话"
    echo "3. 广播消息"
    echo "4. 检查消息状态"
    echo "5. 退出"
    echo ""

    read -p "选择: " choice

    case $choice in
        1)
            read -p "目标用户名: " user
            read -p "目标tty(如pts/0): " tty
            read -p "消息内容: " message
            send_message_write "$user" "$tty" "$message"
            ;;
        2)
            read -p "目标用户名: " user
            read -p "目标主机(默认localhost): " host
            start_talk "$user" "${host:-localhost}"
            ;;
        3)
            read -p "广播消息: " message
            broadcast_message "$message"
            ;;
        4)
            who | while read user tty rest; do
                check_user_mesg "$user" "$tty"
            done
            ;;
        5)
            echo "退出"
            exit 0
            ;;
        *)
            echo "无效选择"
            ;;
    esac
}

# 7. 自动消息系统
auto_message_system() {
    # 监控新登录用户并发送欢迎消息
    while true; do
        # 获取当前登录用户
        current_users=$(who | awk '{print $1" "$2}')

        # 检查是否有新用户
        for user_tty in $current_users; do
            user=$(echo "$user_tty" | awk '{print $1}')
            tty=$(echo "$user_tty" | awk '{print $2}')

            # 检查是否已发送过欢迎消息
            if [ ! -f "/tmp/welcomed_$user_$tty" ]; then
                # 发送欢迎消息
                echo "欢迎 $user! 登录时间: $(date)" | write "$user" "$tty" 2>/dev/null

                # 标记已发送
                touch "/tmp/welcomed_$user_$tty"
            fi
        done

        sleep 60  # 每分钟检查一次
    done
}

# 8. 消息日志系统
message_logging_system() {
    LOG_DIR="/var/log/user_messages"
    mkdir -p "$LOG_DIR"

    # 监控所有write消息
    while read -r line; do
        timestamp=$(date '+%Y-%m-%d %H:%M:%S')
        echo "[$timestamp] $line" >> "$LOG_DIR/messages.log"
    done
}

# 9. 安全消息系统
secure_message_system() {
    # 只允许特定用户发送消息
    ALLOWED_SENDERS=("admin" "operator")
    ALLOWED_RECEIVERS=("alice" "bob" "charlie")

    send_secure_message() {
        local sender=$1
        local receiver=$2
        local message=$3

        # 检查发送者权限
        if [[ ! " ${ALLOWED_SENDERS[@]} " =~ " ${sender} " ]]; then
            echo "错误: $sender 无权发送消息"
            return 1
        fi

        # 检查接收者权限
        if [[ ! " ${ALLOWED_RECEIVERS[@]} " =~ " ${receiver} " ]]; then
            echo "错误: 不能向 $receiver 发送消息"
            return 1
        fi

        # 发送消息
        echo "$message" | write "$receiver"
    }
}

# 10. 消息状态监控
monitor_message_status() {
    echo "消息状态监控 - 更新于: $(date)"
    echo "========================================"

    who | while read user tty from date time; do
        status=$(sudo -u "$user" mesg 2>/dev/null || echo "未知")
        echo "$user ($tty): $status"
    done

    echo "========================================"
}

# 11. 批量消息操作
batch_message_operations() {
    # 为所有用户启用消息
    enable_all_messages() {
        who | awk '{print $1}' | sort -u | while read user; do
            sudo -u "$user" mesg y 2>/dev/null && echo "已为 $user 启用消息"
        done
    }

    # 为所有用户禁用消息
    disable_all_messages() {
        who | awk '{print $1}' | sort -u | while read user; do
            sudo -u "$user" mesg n 2>/dev/null && echo "已为 $user 禁用消息"
        done
    }
}

# 12. 消息系统测试
test_message_system() {
    echo "测试消息系统..."

    # 测试当前用户的消息功能
    echo "1. 测试当前用户:"
    mesg y
    echo "状态: $(mesg)"

    # 测试write功能
    echo -e "\n2. 测试write功能:"
    current_user=$(whoami)
    current_tty=$(tty | cut -d/ -f3-)

    echo "向自己发送测试消息..."
    echo "测试消息 from $(date)" | write "$current_user" "$current_tty"

    # 测试禁用功能
    echo -e "\n3. 测试禁用功能:"
    mesg n
    echo "尝试发送消息到禁用状态..."
    echo "此消息不应显示" | write "$current_user" "$current_tty" 2>/dev/null

    # 恢复状态
    mesg y
    echo "测试完成"
}

# 13. 主菜单
main_menu() {
    while true; do
        clear
        echo "=== 用户消息系统 ==="
        echo ""
        echo "1. 消息工具"
        echo "2. 消息状态监控"
        echo "3. 批量消息操作"
        echo "4. 测试消息系统"
        echo "5. 自动消息系统"
        echo "6. 当前消息状态"
        echo "0. 退出"
        echo ""

        read -p "选择: " choice

        case $choice in
            1) message_tool ;;
            2) monitor_message_status ;;
            3)
                echo "1. 为所有用户启用消息"
                echo "2. 为所有用户禁用消息"
                read -p "选择: " batch_choice
                case $batch_choice in
                    1) enable_all_messages ;;
                    2) disable_all_messages ;;
                esac
                ;;
            4) test_message_system ;;
            5)
                echo "启动自动消息系统 (Ctrl+C停止)"
                auto_message_system
                ;;
            6)
                echo "当前消息状态: $(mesg)"
                who
                ;;
            0)
                echo "退出"
                exit 0
                ;;
            *)
                echo "无效选择"
                ;;
        esac

        echo ""
        read -p "按回车键继续..."
    done
}

# 运行主菜单
main_menu

示例3:系统管理和安全配置

mesg在系统管理和安全方面的应用:

#!/bin/bash
# 系统管理和安全配置

# 1. 系统范围的消息策略
system_wide_policy() {
    echo "配置系统范围的消息策略..."

    # 检查当前策略
    echo "当前系统策略:"
    grep -r "mesg" /etc/profile /etc/bash.bashrc /etc/bashrc /etc/skel 2>/dev/null || echo "无系统策略"

    # 建议的系统策略
    cat > /tmp/system_mesg_policy.txt << 'EOF'
# 系统消息策略建议
# =====================================

# 1. 生产服务器:默认禁用消息
#    在/etc/profile中添加:
#    if [ -t 0 ]; then
#        mesg n 2>/dev/null || true
#    fi

# 2. 开发服务器:默认启用消息
#    在/etc/profile中添加:
#    if [ -t 0 ]; then
#        mesg y 2>/dev/null || true
#    fi

# 3. 根据不同用户组设置不同策略
#    在/etc/profile中添加:
#    if [ -t 0 ]; then
#        if groups $USER | grep -q "developers"; then
#            mesg y
#        else
#            mesg n
#        fi
#    fi

# 4. 根据时间设置策略
#    在/etc/profile中添加:
#    if [ -t 0 ]; then
#        hour=$(date +%H)
#        if [ $hour -ge 9 ] && [ $hour -lt 18 ]; then
#            mesg y  # 工作时间启用
#        else
#            mesg n  # 非工作时间禁用
#        fi
#    fi
EOF

    echo "策略建议已保存到: /tmp/system_mesg_policy.txt"
}

# 2. 安全审计配置
security_audit_config() {
    echo "配置消息安全审计..."

    # 创建审计脚本
    cat > /usr/local/bin/mesg_audit.sh << 'EOF'
#!/bin/bash
# 消息系统审计脚本
AUDIT_LOG="/var/log/mesg_audit.log"

log_event() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$AUDIT_LOG"
}

# 记录所有消息发送尝试
monitor_messages() {
    # 监控/dev/pts设备
    inotifywait -m -e modify /dev/pts/ 2>/dev/null | while read path action file; do
        if [ -n "$file" ]; then
            tty="/dev/pts/${file}"
            user=$(stat -c "%U" "$tty" 2>/dev/null)
            status=$(sudo -u "$user" mesg 2>/dev/null || echo "unknown")

            log_event "TTY访问: $tty, 用户: $user, 消息状态: $status"
        fi
    done
}

# 定期检查消息状态
check_status() {
    while true; do
        who | while read user tty rest; do
            status=$(sudo -u "$user" mesg 2>/dev/null || echo "unknown")
            log_event "状态检查: $user ($tty) = $status"
        done
        sleep 300  # 每5分钟检查一次
    done
}

# 运行审计
log_event "=== 消息审计开始 ==="
monitor_messages &
check_status &
EOF

    chmod +x /usr/local/bin/mesg_audit.sh
    echo "审计脚本已创建: /usr/local/bin/mesg_audit.sh"
}

# 3. 入侵检测集成
intrusion_detection() {
    echo "配置入侵检测..."

    cat > /etc/security/mesg_ids.rules << 'EOF'
# 消息系统入侵检测规则
# =====================================

# 规则1: 频繁消息发送
# 如果同一用户在60秒内发送超过10条消息,触发警报
RULE frequent_messages {
    condition: $MSG_COUNT > 10 in 60s
    action: alert("频繁消息发送: $USER")
}

# 规则2: 向多个用户广播
# 如果用户在短时间内向超过5个不同用户发送消息,触发警报
RULE broadcast_attack {
    condition: $UNIQUE_RECEIVERS > 5 in 120s
    action: alert("可疑广播: $USER")
}

# 规则3: 非工作时间活动
# 如果在非工作时间(22:00-06:00)发送消息,记录日志
RULE after_hours {
    condition: $HOUR < 6 or $HOUR >= 22
    action: log("非工作时间消息: $USER -> $RECEIVER")
}

# 规则4: 权限提升尝试
# 如果普通用户尝试向root发送消息,触发警报
RULE privilege_escalation {
    condition: $RECEIVER == "root" and $USER != "root"
    action: alert("权限提升尝试: $USER -> root")
}
EOF

    echo "入侵检测规则已保存到: /etc/security/mesg_ids.rules"
}

# 4. 合规性检查
compliance_check() {
    echo "运行合规性检查..."

    cat > /tmp/mesg_compliance_check.sh << 'EOF'
#!/bin/bash
# 消息系统合规性检查
COMPLIANCE_LOG="/var/log/mesg_compliance.log"

check_compliance() {
    local score=0
    local total=6

    echo "=== 消息系统合规性检查 ==="
    echo "检查时间: $(date)"
    echo ""

    # 检查1: root用户是否禁用消息
    echo "检查1: root用户消息状态"
    if sudo -u root mesg 2>/dev/null | grep -q "is n"; then
        echo "✓ root用户消息已禁用"
        ((score++))
    else
        echo "✗ root用户消息未禁用(安全风险)"
    fi

    # 检查2: 系统账户是否禁用消息
    echo -e "\n检查2: 系统账户消息状态"
    local system_users=$(getent passwd | grep -E ":/bin/false$|:/usr/sbin/nologin$" | cut -d: -f1)
    local all_ok=true

    for user in $system_users; do
        if sudo -u "$user" mesg 2>/dev/null | grep -q "is y"; then
            echo "警告: 系统账户 $user 启用了消息"
            all_ok=false
        fi
    done

    if $all_ok; then
        echo "✓ 所有系统账户消息已禁用"
        ((score++))
    else
        echo "✗ 有系统账户启用了消息"
    fi

    # 检查3: 是否有全局策略
    echo -e "\n检查3: 系统范围消息策略"
    if grep -r "mesg" /etc/profile /etc/bash.bashrc 2>/dev/null | grep -q "mesg n"; then
        echo "✓ 存在禁用消息的全局策略"
        ((score++))
    else
        echo "✗ 无全局消息策略"
    fi

    # 检查4: 审计日志配置
    echo -e "\n检查4: 消息审计日志"
    if [ -f "/var/log/mesg_audit.log" ] || [ -f "/var/log/user_messages" ]; then
        echo "✓ 存在消息审计日志"
        ((score++))
    else
        echo "✗ 无消息审计日志"
    fi

    # 检查5: write命令权限
    echo -e "\n检查5: write命令权限"
    write_path=$(which write 2>/dev/null)
    if [ -n "$write_path" ]; then
        perms=$(stat -c "%a" "$write_path")
        if [ "$perms" = "4755" ] || [ "$perms" = "4750" ]; then
            echo "✓ write命令权限正确"
            ((score++))
        else
            echo "✗ write命令权限可能存在问题: $perms"
        fi
    fi

    # 检查6: talk服务状态
    echo -e "\n检查6: talk服务状态"
    if systemctl is-active talk.socket 2>/dev/null | grep -q "active"; then
        echo "警告: talk服务正在运行(安全考虑)"
    else
        echo "✓ talk服务未运行"
        ((score++))
    fi

    # 计算结果
    echo -e "\n=== 检查结果 ==="
    echo "得分: $score/$total"
    percentage=$((score * 100 / total))
    echo "合规率: $percentage%"

    if [ $percentage -ge 80 ]; then
        echo "状态: ✓ 合规"
    elif [ $percentage -ge 60 ]; then
        echo "状态: ⚠ 部分合规"
    else
        echo "状态: ✗ 不合规"
    fi
}

# 运行检查
check_compliance | tee -a "$COMPLIANCE_LOG"
EOF

    chmod +x /tmp/mesg_compliance_check.sh
    echo "合规性检查脚本已创建: /tmp/mesg_compliance_check.sh"
}

# 5. 备份和恢复配置
backup_restore_config() {
    echo "备份和恢复消息配置..."

    # 备份函数
    backup_mesg_config() {
        local backup_dir="/backup/mesg_config_$(date +%Y%m%d_%H%M%S)"
        mkdir -p "$backup_dir"

        echo "备份消息配置到: $backup_dir"

        # 备份系统配置文件
        cp /etc/profile "$backup_dir/"
        cp /etc/bash.bashrc "$backup_dir/" 2>/dev/null
        cp /etc/bashrc "$backup_dir/" 2>/dev/null

        # 备份用户配置
        for user in $(getent passwd | cut -d: -f1); do
            user_home=$(getent passwd "$user" | cut -d: -f6)
            if [ -f "$user_home/.bashrc" ]; then
                user_backup_dir="$backup_dir/users/$user"
                mkdir -p "$user_backup_dir"
                cp "$user_home/.bashrc" "$user_backup_dir/"
                cp "$user_home/.profile" "$user_backup_dir/" 2>/dev/null
            fi
        done

        # 创建恢复脚本
        cat > "$backup_dir/restore.sh" << 'EOF'
#!/bin/bash
# 消息配置恢复脚本
BACKUP_DIR=$(dirname "$0")

echo "恢复消息配置..."
echo "备份目录: $BACKUP_DIR"

# 恢复系统配置
if [ -f "$BACKUP_DIR/profile" ]; then
    echo "恢复/etc/profile..."
    sudo cp "$BACKUP_DIR/profile" /etc/profile
fi

if [ -f "$BACKUP_DIR/bash.bashrc" ]; then
    echo "恢复/etc/bash.bashrc..."
    sudo cp "$BACKUP_DIR/bash.bashrc" /etc/bash.bashrc
fi

if [ -f "$BACKUP_DIR/bashrc" ]; then
    echo "恢复/etc/bashrc..."
    sudo cp "$BACKUP_DIR/bashrc" /etc/bashrc
fi

# 恢复用户配置
if [ -d "$BACKUP_DIR/users" ]; then
    for user_dir in "$BACKUP_DIR/users"/*; do
        if [ -d "$user_dir" ]; then
            user=$(basename "$user_dir")
            user_home=$(getent passwd "$user" | cut -d: -f6 2>/dev/null)

            if [ -n "$user_home" ] && [ -d "$user_home" ]; then
                echo "恢复用户 $user 配置..."

                if [ -f "$user_dir/.bashrc" ]; then
                    cp "$user_dir/.bashrc" "$user_home/"
                fi

                if [ -f "$user_dir/.profile" ]; then
                    cp "$user_dir/.profile" "$user_home/" 2>/dev/null
                fi
            fi
        fi
    done
fi

echo "恢复完成"
EOF

        chmod +x "$backup_dir/restore.sh"

        # 创建压缩包
        tar -czf "$backup_dir.tar.gz" -C "$backup_dir" .
        echo "备份压缩包: $backup_dir.tar.gz"
    }

    # 恢复函数
    restore_mesg_config() {
        local backup_file=$1

        if [ ! -f "$backup_file" ]; then
            echo "错误: 备份文件不存在: $backup_file"
            return 1
        fi

        echo "从 $backup_file 恢复配置..."

        # 解压备份
        temp_dir=$(mktemp -d)
        tar -xzf "$backup_file" -C "$temp_dir"

        # 运行恢复脚本
        if [ -f "$temp_dir/restore.sh" ]; then
            bash "$temp_dir/restore.sh"
        else
            echo "错误: 恢复脚本不存在"
        fi

        # 清理临时目录
        rm -rf "$temp_dir"
    }

    echo "备份和恢复功能已定义"
    echo "使用: backup_mesg_config 进行备份"
    echo "使用: restore_mesg_config <备份文件> 进行恢复"
}

# 6. 监控和报警
monitoring_alerting() {
    echo "配置监控和报警..."

    cat > /usr/local/bin/mesg_monitor.sh << 'EOF'
#!/bin/bash
# 消息系统监控脚本
ALERT_EMAIL="admin@example.com"
LOG_FILE="/var/log/mesg_monitor.log"
ALERT_THRESHOLD=10  # 每分钟消息阈值

# 监控消息活动
monitor_messages() {
    local last_count=0

    while true; do
        # 获取当前消息计数
        current_count=$(find /dev/pts/ -type c -name "[0-9]*" 2>/dev/null | wc -l)
        active_messages=$((current_count - last_count))

        # 记录日志
        echo "$(date) - 活动消息: $active_messages" >> "$LOG_FILE"

        # 检查阈值
        if [ $active_messages -gt $ALERT_THRESHOLD ]; then
            send_alert "高消息活动" "检测到高消息活动: $active_messages 条/分钟"
        fi

        # 检查异常用户
        check_abnormal_users

        last_count=$current_count
        sleep 60
    done
}

# 检查异常用户
check_abnormal_users() {
    # 获取消息状态变化的用户
    who | while read user tty rest; do
        status=$(sudo -u "$user" mesg 2>/dev/null)

        # 检查状态是否频繁变化
        if grep -q "用户 $user 状态变化" "$LOG_FILE" | tail -5; then
            send_alert "状态频繁变化" "用户 $user 消息状态频繁变化"
        fi
    done
}

# 发送报警
send_alert() {
    local subject=$1
    local message=$2

    echo "ALERT: $subject - $message" >> "$LOG_FILE"

    # 发送邮件
    echo "$message" | mail -s "消息系统报警: $subject" "$ALERT_EMAIL"

    # 发送系统日志
    logger -p user.alert "mesg监控: $subject - $message"
}

# 启动监控
monitor_messages
EOF

    chmod +x /usr/local/bin/mesg_monitor.sh
    echo "监控脚本已创建: /usr/local/bin/mesg_monitor.sh"

    # 创建systemd服务
    cat > /etc/systemd/system/mesg-monitor.service << EOF
[Unit]
Description=Message System Monitor
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/mesg_monitor.sh
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

    echo "Systemd服务已创建: /etc/systemd/system/mesg-monitor.service"
}

# 7. 主菜单
main_menu() {
    while true; do
        clear
        echo "=== 消息系统管理和安全配置 ==="
        echo ""
        echo "1. 系统范围策略配置"
        echo "2. 安全审计配置"
        echo "3. 入侵检测配置"
        echo "4. 合规性检查"
        echo "5. 备份和恢复配置"
        echo "6. 监控和报警配置"
        echo "7. 运行所有配置"
        echo "0. 退出"
        echo ""

        read -p "选择: " choice

        case $choice in
            1) system_wide_policy ;;
            2) security_audit_config ;;
            3) intrusion_detection ;;
            4) compliance_check ;;
            5) backup_restore_config ;;
            6) monitoring_alerting ;;
            7)
                echo "运行所有配置..."
                system_wide_policy
                security_audit_config
                intrusion_detection
                compliance_check
                backup_restore_config
                monitoring_alerting
                echo "所有配置完成"
                ;;
            0)
                echo "退出"
                exit 0
                ;;
            *)
                echo "无效选择"
                ;;
        esac

        echo ""
        read -p "按回车键继续..."
    done
}

# 运行主菜单
main_menu

常见问题

故障排查:

  1. 检查命令是否存在:
    which mesg
    # 应该输出: /usr/bin/mesg
    # 如果没有,安装coreutils
    sudo apt-get install coreutils
  2. 检查权限问题:
    # mesg需要修改tty设备权限
    ls -la $(tty)
    # 输出示例: crw--w---- 1 user tty
    # 如果用户不在tty组,可能无法修改
    
    # 检查用户组
    groups $USER
    # 确保用户在tty组中
    
    # 如果没有,添加用户到tty组
    sudo usermod -a -G tty $USER
    # 重新登录使更改生效
  3. 检查shell配置冲突:
    # 某些shell配置可能覆盖mesg设置
    # 检查~/.bashrc, ~/.profile, ~/.bash_profile
    grep -n "mesg" ~/.bashrc ~/.profile ~/.bash_profile 2>/dev/null
    
    # 如果有冲突的行,注释掉或修改
    # 例如: mesg n || true
  4. 检查系统策略:
    # 系统可能强制设置了策略
    grep -r "mesg" /etc/profile /etc/bash.bashrc 2>/dev/null
    
    # 如果是只读文件系统或受限环境
    # 检查是否是容器或chroot环境
    ls -la / | head -5
  5. 手动测试权限:
    # 手动修改tty权限测试
    TTY=$(tty)
    echo "当前TTY: $TTY"
    
    # 尝试启用消息
    chmod g+w $TTY
    ls -la $TTY
    # 应该显示: crw--w----
    
    # 尝试禁用消息
    chmod g-w $TTY
    ls -la $TTY
    # 应该显示: crw-------
  6. 使用strace调试:
    # 使用strace查看命令执行
    strace mesg y 2>&1 | tail -20
    # 查看系统调用,检查错误

自动配置方法:

  1. 在用户配置文件中设置:
    # 添加到 ~/.bashrc
    # 登录时自动设置
    if [ -t 0 ]; then
        mesg n 2>/dev/null || true
    fi
    
    # 或根据条件设置
    if [ -t 0 ]; then
        # 工作时间启用,非工作时间禁用
        hour=$(date +%H)
        if [ $hour -ge 9 ] && [ $hour -lt 18 ]; then
            mesg y
        else
            mesg n
        fi
    fi
  2. 在系统配置文件中设置:
    # 在 /etc/profile 中为所有用户设置
    # 添加在文件末尾
    if [ -t 0 ]; then
        # 生产服务器:默认禁用
        mesg n 2>/dev/null || true
    
        # 或根据用户组设置
        if groups $USER | grep -q "developers"; then
            mesg y
        else
            mesg n
        fi
    fi
  3. 使用PAM模块:
    # 创建PAM模块配置文件
    sudo nano /etc/pam.d/mesg
    # 内容:
    # session optional pam_exec.so /usr/local/bin/set_mesg.sh
    
    # 创建设置脚本
    cat > /usr/local/bin/set_mesg.sh << 'EOF'
    #!/bin/bash
    # PAM登录时设置mesg
    if [ "$PAM_TYPE" = "open_session" ]; then
        sudo -u "$PAM_USER" mesg n
    fi
    EOF
    chmod +x /usr/local/bin/set_mesg.sh
  4. 使用systemd服务:
    # 创建systemd用户服务
    mkdir -p ~/.config/systemd/user
    cat > ~/.config/systemd/user/mesg.service << 'EOF'
    [Unit]
    Description=Set mesg on login
    After=default.target
    
    [Service]
    Type=oneshot
    ExecStart=/usr/bin/mesg n
    RemainAfterExit=yes
    
    [Install]
    WantedBy=default.target
    EOF
    
    # 启用服务
    systemctl --user enable mesg.service
    systemctl --user start mesg.service
  5. 使用cron定时任务:
    # 添加cron任务
    crontab -e
    # 添加以下行:
    # 每天9点启用消息
    0 9 * * * mesg y
    # 每天18点禁用消息
    0 18 * * * mesg n
    # 每分钟检查并设置
    * * * * * /usr/local/bin/check_and_set_mesg.sh
  6. 使用登录钩子:
    # 在 /etc/bash.bashrc 或 /etc/profile 中添加
    # SSH登录时特殊处理
    if [ -n "$SSH_CONNECTION" ]; then
        mesg n
    fi
    
    # 根据终端类型设置
    case $(tty) in
        /dev/tty[0-9]*)
            mesg y  # 控制台终端启用
            ;;
        /dev/pts/[0-9]*)
            mesg n  # 伪终端禁用
            ;;
    esac

mesg在现代系统中的角色:

  1. 安全加固:
    # 在生产服务器上禁用消息,防止干扰
    # 添加到安全加固脚本
    echo "禁用终端消息..." >> /var/log/hardening.log
    mesg n
    
    # 检查安全合规
    if mesg | grep -q "is y"; then
        echo "警告: 消息接收已启用" >> /var/log/security.log
    fi
  2. 容器环境:
    # 在Docker容器中通常不需要消息
    # Dockerfile中禁用
    RUN echo "mesg n" >> /etc/profile
    
    # 在Kubernetes中
    # Pod securityContext中可能需要处理
    securityContext:
      capabilities:
        drop: ["SYS_TTY_CONFIG"]
  3. 自动化脚本:
    # 在自动化任务中防止消息干扰
    setup_automation() {
        # 保存当前状态
        MESG_STATE=$(mesg | awk '{print $2}')
    
        # 禁用消息
        mesg n
    
        # 运行自动化任务
        ./automated_task.sh
    
        # 恢复原状态
        mesg $MESG_STATE
    }
  4. CI/CD管道:
    # 在Jenkins/GitLab CI中
    pipeline {
        agent any
        stages {
            stage('Setup') {
                steps {
                    sh '''
                        # 禁用消息防止干扰
                        mesg n || true
                        echo "消息接收已禁用"
                    '''
                }
            }
        }
    }
  5. 桌面环境:
    # 在现代桌面环境中,mesg可能被其他机制替代
    # 但仍在某些场景有用
    
    # GNOME终端可能忽略mesg设置
    # 检查桌面环境
    echo $XDG_CURRENT_DESKTOP
    
    # 使用dbus或其他机制替代
    dbus-send --session --type=method_call \
        --dest=org.gnome.Terminal \
        /org/gnome/Terminal \
        org.gnome.Terminal.SetProperty \
        string:'allow-remote' boolean:false
  6. 向后兼容:
    # 保持与旧脚本的兼容性
    # 许多旧脚本可能依赖mesg
    
    # 包装函数保持兼容
    legacy_mesg() {
        if [ "$1" = "y" ]; then
            # 现代替代方案
            systemctl --user import-environment DISPLAY
        elif [ "$1" = "n" ]; then
            # 现代禁用方案
            systemctl --user unset-environment DISPLAY
        else
            # 默认行为
            command mesg "$@"
        fi
    }