perl: system interaction

本文深入探讨了Perl语言中进程控制的基础知识,包括如何使用exit值来标记进程的退出状态、system与exec的区别及其应用场景、如何通过管道进行进程间的数据交换以及信号量的使用方法。

The following topics will be covered.

 

Exit value ;

system & exec - block the present process & swith to a new process, wait for them to finish before returning to next.

capture output - `` & qx{}

pipe - read in/from a process

signal - kill $signal, $pid

 

1. Exit Value

exit(0); equals to exit;

exit value must less than 256.


2. system VS. exec

perl always use /bin/sh -c to interpret the command.

e.g. system("notepad file.txt");

 

if (($pid=fork) == 0)

{

    # pid=29662; 29662 called exec, aa.sh was executed in 29662, never run statements after exec
    #exec(" /test/aa.sh");

 

    # pid=576; 576 called exec, generated two sub-process 577&579 for both aa.sh's execution
    #exec("/test/aa.sh | /test/aa.sh");

    # pid=17697; 17697 called system to generate a sub-process 17698, 17698 forked 17699&17701 for both aa.sh's execution
    # after all sub-process exited, returned back to 17697 to run statements after system;

    system("/test/aa.sh | /test/aa.sh");

 

    # pid=5949; 5949 call system to fork 5950 to run aa.sh
    system("/test/aa.sh");

    my $tmp = `ps -ef|grep aa.sh|grep -v grep`; print "$tmp/n";

    exit 0;

}

 

multiple argument system (better to use this version of system)

system('command', 'arg1', 'arg2', ...);

system('command', @argv);

1. arguments are treated literally instead of passed via the shell

2. bypass the shell, avoid unintentional interpretation of shell meta-chars.

 

Note:

system never fail, although the process it starts may fail, we should check $? for the status.

$? :return vaule of process

0 -- success

-1 -- process never start, $1 stores the reason.

exit value:        $? >> 8;

signal number: $? & 127;

dump core:       $? & 128

 

simple:

use IPC::System::Simple qw(system);

 

exec

All is the same with system, except perl will leave the current program and execute the new process.

when we need to prepare a lot of work for the process, we can use exec.

multi-argu exec version is better.

 

 

3. Pipe open

open a pipe to read data from a process .

open(my $ssh, "ssh $host cat $file |") or die "Can't open pipe: $!";

 

Note:

open never fail if perl always can open a pipe, although the process may fail

e.g.

open(my $rsh, "catt non-exist file 2>/dev/null|") or die "Can't open pipe: $!"; >>>> OK

open(my $rsh, "catt non-exist file |") or die "Can't open pipe: $!"; >>>> open failed.

open(my $rsh, "cat non-exist file |") or die "Can't open pipe: $!";  >>>> OK

 

open a pipe to or send data to a process

we need to set up a handler to catch any SIGPIPES.

local $SIG{PIPE} = sub { die "pipe broke" };
open(my $out, " | xargs cat") or die $!;
print $out "system_inter.pl";
close $out;

 

This open passes command via shell, to avoid this, we use multi-arg open version

open(my $ssh, "-|",  "ssh", $host, "cat", $file)

open(my $out, "|-", $process1);

 

4. signal

kill 0, $pid

---return 1 if pid is alive;

---return 0 if pid is not alive;

$$--- pid of the program itself

 

kill $signal, -$pid;

send $signal to $pid and its process-group, usually its children.

 

kill -l;

list all available signals on the system.

 

 

 

 

 

 

 

 

<think> 我们注意到错误信息中提到了两个关键点: 1. 所有目标文件(build/14_random_usage_list.xdv 和 build/14_random_usage_list.pdf)已经是最新的(up-to-date) 2. 但同时又提到xdvipdfmx在之前的调用中出现了错误,并且最终返回错误代码12 这种情况通常发生在编译过程被中断或部分失败后,latexmk认为目标文件已经存在且是最新的,因此不再重新编译,但实际上这些文件可能是不完整的或损坏的。 解决方案: 1. 强制清理并重新编译: 在终端中运行以下命令(在项目目录下): ```bash latexmk -c # 清理辅助文件,但保留PDF latexmk -C # 清理所有生成的文件(包括PDF) latexmk -f -xelatex -interaction=nonstopmode -file-line-error -outdir=build 14_random_usage_list.tex ``` 2. 如果上述方法无效,则需手动删除生成的文件: - 删除整个`build`目录 - 然后重新运行编译 3. 检查输出目录的写入权限: - 确保你有权限在`build`目录中创建和删除文件 4. 检查文件是否被其他进程锁定: - 确保没有其他程序(如PDF阅读器)正在打开`build/14_random_usage_list.pdf`文件 5. 在VS Code中配置LaTeX Workshop扩展以强制重新编译: - 修改`settings.json`,添加以下选项强制每次编译前清理: ```json "latex-workshop.latex.autoBuild.cleanAndRetry.enabled": true, "latex-workshop.latex.clean.subfolder.enabled": true, "latex-workshop.latex.clean.fileTypes": [ "*.aux", "*.bbl", "*.blg", "*.idx", "*.ind", "*.lof", "*.lot", "*.out", "*.toc", "*.acn", "*.acr", "*.alg", "*.glg", "*.glo", "*.gls", "*.ist", "*.fls", "*.log", "*.fdb_latexmk", "*.xdv", "*.snm", "*.nav", "*.synctex.gz" ] ``` 6. 如果问题依旧,尝试使用不同的编译引擎(如pdflatex)测试,以排除xelatex引擎的问题。 ### 注意事项 - 错误代码12通常表示外部命令执行失败(这里是xdvipdfmx),可能是由于文件系统问题(权限、锁定)或路径问题。 - 确保你的文件路径中没有空格和特殊字符(尽管你当前路径有下划线,这是允许的,但注意`STQC_OLD`中的横线`-`在路径中出现,这通常不会引起问题,但最好避免)。 §§相关问题§§ 1. 如何配置latexmk使其在每次编译前自动清理辅助文件? 2. 当LaTeX项目中的部分文件更新后,如何强制latexmk重新编译整个项目? 3. 在Windows系统中,如何通过命令行检测并解除对指定文件的占用? 4. 如何修改VS Code的LaTeX Workshop扩展配置,以支持在编译失败时自动清理并重试? 5. 使用xelatex编译时,出现字体相关错误的常见解决方法有哪些? </think>### 回答你的问题 这个错误表明 LaTeX 编译环境存在状态不一致问题:虽然 `latexmk` 检测到文件已最新,但之前的 `xdvipdfmx` 错误导致编译流程中断。以下是系统性的解决方案: #### 核心问题与修复步骤 ```markdown 1. **强制清理编译缓存**: - 在项目根目录运行: ```bash latexmk -c # 清理常规文件 latexmk -C # 清理所有生成文件(包括PDF) rm -rf build # 删除整个输出目录 ``` 2. **重建目录结构**: - 手动创建 `build` 目录并验证权限: ```powershell mkdir build icacls build /grant "Users:(OI)(CI)F" # Windows赋权 ``` 3. **强制完整重新编译**: - 添加 `-g` 参数忽略状态检查: ```bash latexmk -g -xelatex -synctex=1 -interaction=nonstopmode -file-line-error --shell-escape -outdir=build 14_random_usage_list.tex ``` 4. **修复文件编码冲突**: - 在文档开头添加编码声明: ```latex % !TEX program = xelatex % !TEX encoding = UTF-8 Unicode \documentclass{article} \usepackage[UTF8]{ctex} % 中文字体支持 ``` #### VS Code 配置优化 修改 `settings.json`: ```json "latex-workshop.latex.autoBuild.run": "never", // 禁用自动编译 "latex-workshop.latex.recipe.default": "lastUsed", "latex-workshop.latex.recipes": [ { "name": "xelatex ➞ bibtex ➞ xelatex×2", "tools": ["xelatex", "bibtex", "xelatex", "xelatex"] } ], "latex-workshop.latex.tools": [ { "name": "xelatex", "command": "xelatex", "args": [ "-synctex=1", "-interaction=nonstopmode", "-halt-on-error", "-output-directory=build", "%DOCFILE%" ] } ] ``` #### 系统环境修复 1. 更新 TeX Live 核心组件: ```bash tlmgr update --all --self tlmgr install latexmk xdvipdfmx ``` 2. 重置文件关联: ```reg Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\.tex] @="TeX.Document" ``` ### 预防措施 - 定期运行 `latexmk -c` 清理项目 - 避免在文件名中使用连字符(`-`),改用下划线(`_`) - 为大型项目创建专用编译脚本: ```bash #!/bin/bash rm -rf build/* latexmk -xelatex -outdir=build $1 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值