forum
forum copied to clipboard
寻找中文用户名 gui 安装报错原因的尝试
首先给一个简化的复现流程:
- 需要使用 iso 文件安装,保证包都是压缩存档。解压 iso(不解压也行,解了方便修改安装脚本)到任意路径如
D:\installer\texlive2022
- 执行
cd D:\installer\texlive2022
set TEXLIVE_INSTALL_PREFIX=D:\texlive-install-test
set path=%cd%\tlpkg\tlperl\bin;%path%
mkdir D:\texlive-install-test\中文临时路径
set temp=D:\texlive-install-test\中文临时路径
(echo startinst^& echo vars^& echo binary_win32: 1^& echo endvars^& rem.) | perl install-tl -from_ext_gui -portable -scheme minimal
报错
Installing to: D:/texlive-install-test
Installing [1/6, time/total: ??:??/??:??]: hyphen-base [22k]
Installing [2/6, time/total: 00:00/00:00]: kpathsea [1087k]
Installing [3/6, time/total: 00:00/00:00]: luatex [1870k]
Installing [4/6, time/total: 00:00/00:00]: texlive-scripts [504k]
Installing [5/6, time/total: 00:01/00:03]: texlive.infra [545k]
Installing [6/6, time/total: 00:01/00:02]: tlperl.win32 [7112k]
Time used for installing the packages: 00:03
Installing [01/55, time/total: ??:??/??:??]: amsfonts [4725k]
Installing [02/55, time/total: 00:01/00:09]: bibtex [405k]
Installing [03/55, time/total: 00:01/00:08]: bibtex.win32 [42k]
open(>D:\texlive-install-test\\x{00d6}D\x{00ce}\x{00c4}áùê±\x{00c2}·\x{00be}\x{00b6}\G2trYrC0F8\GewtiUL0jM/bibtex.win32.r62513.tar.xz) failed: No such file or directory at tlpkg/TeXLive/TLUtils.pm line 1383, <STDIN> line 4.
原因及修复
install-tl
的180-182行(HEAD里是176-178)
binmode (STDIN, ':encoding(console_in)');
binmode (STDOUT, ':encoding(console_out)');
binmode (STDERR, ':encoding(console_out)');
删除 binmode (STDIN, ':encoding(console_in)');
将不再报错,删除后两行输出编码不再错误。
引入这个问题的提交是rev58646 https://tug.org/pipermail/tex-live-commits/2021-March/017368.html 以及后续的 rev58690 https://tug.org/pipermail/tex-live-commits/2021-March/017412.html。在rev58646的提交记录里写着
**Log Message: ** installer@windows: make sure that output is not scrambled on non-utf8 setups
Patch by Masamichi Hosoda
我不太清楚当时修复了什么编码问题,但现在看来,没有这个修复反而不会出错。
暂时不确定这么修改是否会引起别的问题,它虽然修好了,但看起来非常可疑,因为安装程序并没有从 stdin 读取 temp 路径。与之相应的有:
一个奇怪的现象
图形界面安装给 install-tl
脚本传入 -from_ext_gui
参数,导致执行脚本 tlpkg\installer\install-menu-extl.pl
。
# reading back current %vars from the frontend
sub read_vars {
my $l = <STDIN>;
chomp $l;
if ($l ne 'vars') {
return 0;
}
while (1) {
$l = <STDIN>;
chomp $l;
if ($l =~ /^([^:]+): (.*)$/) {
$vars{$1} = $2;
} elsif ($l eq 'endvars') {
$vars{'free_size'} = TeXLive::TLUtils::diskfree($vars{'TEXDIR'});
return 1;
} else {
return 0;
}
}
return 0;
}
输入的 binary_win32: 1
用 /^([^:]+): (.*)$/
匹配的结果是 $1="binary_win32" && $2="1"
,也就是说执行了 $vars{"binary_win32"} = "1"
,但是如果把
$vars{$1} = $2;
改成
$vars{$1} = $2;
if ($1 eq 'binary_win32') {
$vars{"binary_win32"} = $2;
}
它居然也不出错。按理说这两个代码效果应该毫无区别,perl 我不太熟悉,可能是什么奇怪的语言特性。
这似乎确实不是一个正常的字符串。
tlpkg\TeXLive\TLPDB.pm
第 1797 行
$container = "$root/$Archive/$pkg.r$rev.tar.$ext";
如果改成
$pkg = "bibtex.win32" if ($pkg eq "bibtex.win32");
$container = "$root/$Archive/$pkg.r$rev.tar.$ext";
就可以阻止 bibtex.win32
处的错误,但是
$pkg =~ s/bibtex\.win32/bibtex.win32/;
没有作用。