我刚刚从 Ubuntu 20.04 升级到 22.04.2 (Linux 5.15.0-67),使用 XFCE 桌面环境,Gnome Terminal 版本 3.44.0。我有一个脚本程序来做备份,多年来我基本上每天都在运行它。这个程序既向终端显示信息,又将信息写入日志文件。
在升级后第一次运行此程序时,我注意到一个奇怪的行为,有时终端的新输出行会按预期下降一行,但会位于前一行之后的下一列,而不是按预期位于最左边的列。这种情况并不总是发生,我看到它在预期行为(所有新行都从最左边的列开始)和 Linux 中 Bash 的这种奇怪行为之间来回跳转。
我查看了日志文件,其中包含的数据比写入终端的数据多得多,并且所有行都按预期从最左边的列开始。
我查看了生成此输出的代码。有时它是一个简单的“echo”命令,有时是“echo -e”,有时它是来自其他命令的输出消息。Echo 命令同时发送到屏幕和日志文件,因此两者的行为应该相同。我尝试编写一个测试脚本来复制该问题,但它运行正常,即使循环 500 个 echo 命令也是如此。
这是终端的输出,显示了问题所在。对于较长的行,它们会在终端中换行,下一行会在换行后的下一列开始。
> ******************************************************************
> ********** backup_type: tar_backup *******************************
> ******************************************************************
>
> ******************************************************************
> ********** group: ubu_ssd1 ***************************************
> ******************************************************************
>
> ******************************************************************
> ********** group: ubu_ssd1, element: root ************************
> ****************************************************************** mounting /dev/vg_ssd1/ubu_root_ssd1_snap on /mnt source device:
> /dev/vg_ssd1/ubu_root_ssd1_snap source directory: /mnt destination
> directory: /home/randy/Backup/home4/ubu_ssd1/update_2023_week_10 tar
> --directory=//mnt --create --one-file-system --no-check-device --auto-compress --warning=no-file-ignored --file=/home/randy/Backup/home4/ubu_ssd1/update_2023_week_10/ubu_root_ssd1_2023_week_10.3.tar
> .
> --listed-incremental=/home/randy/Backup/home4/ubu_ssd1/update_2023_week_10/ubu_root_ssd1_2023_week_10.snar
> tar update "/mnt" to
> "/home/randy/Backup/home4/ubu_ssd1/update_2023_week_10/ubu_root_ssd1_2023_week_10.3.tar"
> completed at 20230308-03:16:23. Elapsed time: 0 hrs 0 min 30 sec
>
> ******************************************************************
> ********** group: ubu_ssd1, element: boot ************************
> ******************************************************************
> source device: sdb8
> source directory: /boot
> destination directory: /home/randy/Backup/home4/ubu_ssd1/update_2023_week_10
> tar --directory=//boot --create --one-file-system --no-check-device --auto-compress --warning=no-file-ignored --file=/home/randy/Backup/home4/ubu_ssd1/update_2023_week_10/ubu_boot_ssd1_2023_week_10.3.tar
> .
> --listed-incremental=/home/randy/Backup/home4/ubu_ssd1/update_2023_week_10/ubu_boot_ssd1_2023_week_10.snar
> tar update "/boot" to "/home/randy/Backup/home4/ubu_ssd1/update_2023_week_10/ubu_boot_ssd1_2023_week_10.3.tar"
> completed at 20230308-03:16:26.
> Elapsed time: 0 hrs 0 min 0 sec
>
> ******************************************************************
> ********** group: ubu_ssd1, element: home ************************
> ****************************************************************** mounting /dev/vg_ssd1/ubu_home_ssd1_snap on /mnt
> source device: /dev/vg_ssd1/ubu_home_ssd1_snap source directory: /mnt
> destination directory: /home/randy/Backup/home4/ubu_ssd1/update_2023_week_10
> tar --directory=//mnt --create --one-file-system --no-check-device
> --auto-compress --warning=no-file-ignored --file=/home/randy/Backup/home4/ubu_ssd1/update_2023_week_10/ubu_home_ssd1_2023_week_10.3.tar
> .
> --listed-incremental=/home/randy/Backup/home4/ubu_ssd1/update_2023_week_10/ubu_home_ssd1_2023_week_10.snar
> tar update "/mnt" to "/home/randy/Backup/home4/ubu_ssd1/update_2023_week_10/ubu_home_ssd1_2023_week_10.3.tar"
> completed at 20230308-03:16:58.
> Elapsed time: 0 hrs 0 min 33 sec
>
> ******************************************************************
> ********** group: data *******************************************
> ******************************************************************
>
> ******************************************************************
> ********** group: data, element: data ****************************
> ******************************************************************
> mounting /dev/vg_data_hd5/data_lv_snap on /mnt
> source device: /dev/vg_data_hd5/data_lv_snap
> source directory: /mnt
> destination directory: /home/randy/Backup/home4/data/update_2023_week_10
> tar --directory=//mnt --create --one-file-system --no-check-device
> --auto-compress --warning=no-file-ignored --file=/home/randy/Backup/home4/data/update_2023_week_10/data_hd5_2023_week_10.3.tar
> .
> --listed-incremental=/home/randy/Backup/home4/data/update_2023_week_10/data_hd5_2023_week_10.snar
> tar update "/mnt" to
> "/home/randy/Backup/home4/data/update_2023_week_10/data_hd5_2023_week_10.3.tar"
> completed at 20230308-03:17:08.
这是日志文件的输出,其中多余的行被删除,表明写入正确。
******************************************************************
********** backup_type: tar_backup *******************************
******************************************************************
******************************************************************
********** group: ubu_ssd1 ***************************************
******************************************************************
******************************************************************
********** group: ubu_ssd1, element: root ************************
******************************************************************
mounting /dev/vg_ssd1/ubu_root_ssd1_snap on /mnt
source device: /dev/vg_ssd1/ubu_root_ssd1_snap
source directory: /mnt
destination directory: /home/randy/Backup/home4/ubu_ssd1/update_2023_week_10
tar --directory=//mnt --create --one-file-system --no-check-device --auto-compress --warning=no-file-ignored --file=/home/randy/Backup/home4/ubu_ssd1/update_2023_week_10/ubu_root_ssd1_2023_week_10.3.tar . --listed-incremental=/home/randy/Backup/home4/ubu_ssd1/update_2023_week_10/ubu_root_ssd1_2023_week_10.snar
tar update "/mnt" to "/home/randy/Backup/home4/ubu_ssd1/update_2023_week_10/ubu_root_ssd1_2023_week_10.3.tar" completed at 20230308-03:16:23.
Elapsed time: 0 hrs 0 min 30 sec
******************************************************************
********** group: ubu_ssd1, element: boot ************************
******************************************************************
source device: sdb8
source directory: /boot
destination directory: /home/randy/Backup/home4/ubu_ssd1/update_2023_week_10
Entering function backup_tar
Entering function check_tar_increment
Returning from function check_tar_increment with value: 3
tar --directory=//boot --create --one-file-system --no-check-device --auto-compress --warning=no-file-ignored --file=/home/randy/Backup/home4/ubu_ssd1/update_2023_week_10/ubu_boot_ssd1_2023_week_10.3.tar . --listed-incremental=/home/randy/Backup/home4/ubu_ssd1/update_2023_week_10/ubu_boot_ssd1_2023_week_10.snar
tar update "/boot" to "/home/randy/Backup/home4/ubu_ssd1/update_2023_week_10/ubu_boot_ssd1_2023_week_10.3.tar" completed at 20230308-03:16:26.
Elapsed time: 0 hrs 0 min 0 sec
******************************************************************
********** group: ubu_ssd1, element: home ************************
******************************************************************
mounting /dev/vg_ssd1/ubu_home_ssd1_snap on /mnt
source device: /dev/vg_ssd1/ubu_home_ssd1_snap
source directory: /mnt
destination directory: /home/randy/Backup/home4/ubu_ssd1/update_2023_week_10
tar --directory=//mnt --create --one-file-system --no-check-device --auto-compress --warning=no-file-ignored --file=/home/randy/Backup/home4/ubu_ssd1/update_2023_week_10/ubu_home_ssd1_2023_week_10.3.tar . --listed-incremental=/home/randy/Backup/home4/ubu_ssd1/update_2023_week_10/ubu_home_ssd1_2023_week_10.snar
tar update "/mnt" to "/home/randy/Backup/home4/ubu_ssd1/update_2023_week_10/ubu_home_ssd1_2023_week_10.3.tar" completed at 20230308-03:16:58.
Elapsed time: 0 hrs 0 min 33 sec
******************************************************************
********** group: data *******************************************
******************************************************************
******************************************************************
********** group: data, element: data ****************************
******************************************************************
mounting /dev/vg_data_hd5/data_lv_snap on /mnt
source device: /dev/vg_data_hd5/data_lv_snap
source directory: /mnt
destination directory: /home/randy/Backup/home4/data/update_2023_week_10
tar --directory=//mnt --create --one-file-system --no-check-device --auto-compress --warning=no-file-ignored --file=/home/randy/Backup/home4/data/update_2023_week_10/data_hd5_2023_week_10.3.tar . --listed-incremental=/home/randy/Backup/home4/data/update_2023_week_10/data_hd5_2023_week_10.snar
tar update "/mnt" to "/home/randy/Backup/home4/data/update_2023_week_10/data_hd5_2023_week_10.3.tar" completed at 20230308-03:17:08.
只是因为您会感兴趣,这里有一些针对有问题的写入行的代码片段。
echo "mounting ${mntpnt_volume} on ${mntpnt}" | tee -a ${gc_logfile};
echo "source device: ${source_device}" | tee -a "${gc_logfile}";
echo "source directory: ${source_directory}" | tee -a "${gc_logfile}";
echo "destination directory: ${dest_directory}" | tee -a "${gc_logfile}";
echo -e "\n${c_stars1}${c_stars2}" | tee -a ${gc_logfile};
echo -e "${c_stars1} ${star_gap_string}" \
"${c_stars2:${star_gap}}" | tee -a ${gc_logfile};
echo -e "${c_stars1}${c_stars2}" | tee -a ${gc_logfile};
前一天我在 20.04 时,这段代码运行良好。有什么想法吗?
编辑:
请参阅下面的回答,其中涉及在命令行中调用 PulseAudio paplay 的时间,我从根目录生成它作为子进程,这需要重置环境变量 XDG_RUNTIME_DIR。
我尝试添加标签 paplay 和 XDG_RUNTIME_DIR,但 StackExchange 说我的声誉不足以使用这些词作为标签。我只是想让其他处于类似情况的人更容易一些。我想我得去获得一些街头信誉。
答案1
好吧,我搞明白了,这可以追溯到很多年前。我编写了处理不同声音输出的函数,这些输出在程序的不同位置和不同条件下播放。PulseAudio paplay 函数需要一些时间才能完成,所以我认为将其作为子进程运行是个好主意,这样父进程就可以继续做其他事情了。一切都很顺利。
如果我没记错的话(但事实并非总是如此),几年前版本升级时情况发生了变化,我不得不添加一个 if 语句来检查此函数是否以 root 身份运行,并通过设置 XDG_RUNTIME_DIR 以不同方式处理 paplay 调用。但这导致了一种错误情况,可能与我现在遇到的情况类似——我不记得了。只有当我将 root 条件 paplay 调用生成到子进程时,才会发生错误情况。我发现,如果我设置 0.7 秒的睡眠延迟,程序就会正常工作,这是 paplay 调用完成所需的时间,即使作为子进程卸载也是如此。我从来没有发现它为什么会这样表现,但我只是在所有声音函数中设置了 0.7 秒的睡眠间隔并忍受了它。这是其中一个声音函数:
function play_norm_sound {
# check if we're running as root.
if [[ $EUID -eq 0 ]]; then
sudo -u '#1000' XDG_RUNTIME_DIR=/run/user/1000 \
paplay "/usr/share/sounds/KDE-Im-Contact-Out.ogg" &
else
paplay "/usr/share/sounds/KDE-Im-Contact-Out.ogg" &
fi
sleep 0.7;
return 0;
}
现在的情况是,paplay 调用现在需要大约 1.1 秒才能完成,因此 0.7 秒的时间不够长。在睡眠间隔的 0.7 秒和完成 paplay 函数的 1.1 秒之间的间隙中,发生了奇怪的行为。这就是为什么有时我会看到它自行纠正,然后又表现得很奇怪。当程序循环并完成某些操作时,我会播放很多声音。
我想到我为什么要费心生成一个子进程,然后设置一个睡眠间隔让它完成?也许在未来的升级中,时间间隔会更大。我可以删除生成字符(行末的“&”),让它在父 shell 的范围内运行,然后删除睡眠间隔调用。我可以将非 root 条件保留为生成子进程,就像它最初所做的那样。
这是新代码:
function play_norm_sound {
# check if we're running as root.
if [[ $EUID -eq 0 ]]; then
sudo -u '#1000' XDG_RUNTIME_DIR=/run/user/1000 \
paplay "/usr/share/sounds/KDE-Im-Contact-Out.ogg";
else
paplay "/usr/share/sounds/KDE-Im-Contact-Out.ogg" &
fi
return 0
}
我不认为这是一个解决方案,因为我应该能够生成一个子进程,这样程序就可以更高效地运行,而不会出现如此奇怪的行为。但这是一种解决方法,这可能是我能做到的极限。
顺便说一句,我发现如果程序在终端显示奇怪行为时结束,那么不良行为从那时起就会在终端中持续存在,并且不会显示任何键盘输入。无论运行任何 stty 命令或更改终端首选项,情况都是如此。唯一要做的就是关闭选项卡、打开新选项卡或关闭终端窗口。Gnome 和 xfce 终端都是如此。