问题描述:
我写了一个wsl的CLI工具来学习rust。 它可以使用 Windows 的 explorer.exe 打开文件。 我称之为“op”。
问题是每次我打开一个新的 wsl 和 在鱼壳中输入“op”, 并使用“Tab”来完成, 然后会出现错误:
> op error: the directory does not exist
Oops: command not found
- (line 1):
Oops "./completion"
^~~^
from sourcing file -
called on line 1 of file /usr/share/fish/completions/op.fish
from sourcing file /usr/share/fish/completions/op.fish
(文本'op'是彩色的,其他是白色的)
/usr/share/fish/completions/op.fish:
op completion fish | source
似乎与 fish shell (3.6.0) 有关(bash 没有错误,因为没有完成)。但是这个错误只会出现一次,之后命令“op”就会像预期的那样有意义。
我在这本书之后有一个'minigrep'。它运行完美,没有错误。
源码(main.rs):
// This is a minimal frame
// The complete code is in https://github.com/GlekoMa/op
use std::env;
use std::path::Path;
use std::process::Command;
fn main() {
// 0. get env args
let args: Vec<String> = env::args().collect();
// 1. convert args[1] to Path
let path = Path::new(&args[1]);
// 2. parse path to parent and file_name
let parent = path.parent().unwrap();
let file_name = path.file_name().unwrap().to_str().unwrap();
// 3. cd parent path
env::set_current_dir(parent).unwrap();
// 4. execute open (using exeplorer.exe) cmd
let cmd_open = format!("explorer.exe {file_name}");
Command::new("sh").arg("-c").arg(cmd_open).output().unwrap();
}
预期行为:
键入“op”并使用“Tab”完成不会引发任何错误。
更新和解决方案
感谢@faho,这个错误的来源(与 rust 源代码无关)描述如下:
/usr/share/fish/completions不知何故有一个补全鱼脚本op.fish(一般是同名软件生成的)。 但是我的“op”没有生成它,所以这个 op.fish 与我的“op”发生冲突。
有两种简单的修复方法:
重命名“op”(不是通过别名而是通过重建)。
将空文件写入 ~/.config/fish/completions/op.fish 以便 fish 加载它而不是 /usr/share/fish/completions/op.fish。
我已经使用了第二种方式,现在“op”效果很好!
您的代码有调试打印:
https://github.com/GlekoMa/op/blob/7ae843acbd37a3f64b162aaf4b984094c7be0aa8/src/main.rs#L17
println!("Oops {:?}", path); // This code is for debug.
这会打印出
Oops ...
,所以 fish 会,因为您告诉它 source
输出,尝试将其作为命令运行,而命令“Oops”将不存在,因此它会打印错误。
这只会在完成加载时发生,鱼通常会在您第一次尝试完成某事时这样做。
删除调试语句,在生成补全时不要打印它(即你得到
completion
子命令),而是将它打印到 stderr(这意味着它会在加载补全时显示!)或者在它前面加上前缀//
发表评论。
我在创建一个最小的可重现示例时找到了错误的来源:
我用相同的代码创建了一个新项目,发现它运行完美,没有这个错误!
所以我删除了文件 /usr/share/fish/completions/op.fish 并尝试在新终端中运行“op”。这次没有出现错误。
为我的愚蠢道歉!