学习Rust的100个练习:快捷更新 VsCode

在 Ubuntu 机器上更新 VsCode 很麻烦。点开 VsCode 官方网址,下载安装包,执行 apt 完成安装,然后再重启 VsCode。
我要做的就是简化这个操作流程,最好是一键完成更新。
之所以使用 Rust 来写这个脚本,纯粹为了练习一下写 Rust。
实现思路
- 下载文件,如果版本一致,则无需更新
- 执行
apt install vscode.deb - kill vscode 的进程
- 启动 vscode
具体实现代码
use std::process::Command;
const DOWNLOAD_URL: &str = "https://code.visualstudio.com/sha/download?build=stable&os=linux-deb-x64";
fn main() {
println!("Downloading VSCode from: {}", DOWNLOAD_URL);
let filename = download_vscode();
println!("VSCode downloaded to: {}", filename);
kill_vscode();
execute_install(&filename);
restart_vscode();
}
下载 VsCode
fn download_vscode() -> String {
let client = reqwest::blocking::Client::builder()
.redirect(reqwest::redirect::Policy::none())
.build()
.expect("Failed to build client");
let response = client.get(DOWNLOAD_URL)
.send()
.expect("Failed to request");
let location = response.headers()
.get("location")
.expect("No location header")
.to_str()
.expect("Invalid location")
.to_string();
let filename = location.rsplit('/').next().unwrap_or("code.deb");
let filepath = format!("/tmp/{}", filename);
if std::path::Path::new(&filepath).exists() {
println!("File exists, skip download: {}", filepath);
return filepath;
}
let mut response = reqwest::blocking::get(&location)
.expect("Failed to download");
let mut out = std::fs::File::create(&filepath)
.expect("Failed to create file");
std::io::copy(&mut response, &mut out)
.expect("Failed to copy content");
println!("Downloaded: {}", filename);
filepath
}
杀死进程
fn kill_vscode() {
// Placeholder for killing VSCode process and filter current pid
println!("Killing any running VSCode instances...");
let pid = std::process::id();
println!("Current PID: {}", pid);
let code_pid_list = Command::new("pgrep")
.arg("code")
.output()
.expect("Failed to execute pgrep")
.stdout;
let code_pid_text = String::from_utf8_lossy(&code_pid_list);
for line in code_pid_text.lines() {
if let Ok(code_pid) = line.parse::<u32>() {
if code_pid != pid {
Command::new("kill")
.arg("-9")
.arg(code_pid.to_string())
.status()
.expect("Failed to kill VSCode process");
}
}
}
}
执行安装
fn execute_install(filename: &str) {
// Placeholder for installation logic
println!("Installing VSCode...");
// Here you would add the actual installation commands
Command::new("sudo")
.arg("apt")
.arg("install")
.arg("-y")
.arg(filename)
.status()
.expect("Failed to install VSCode");
println!("VSCode installed successfully!");
}
重启 VsCode
fn restart_vscode() {
// Placeholder for restarting VSCode process
println!("Restarting VSCode...");
Command::new("code")
.status()
.expect("Failed to restart VSCode");
}
编译和创建快捷指令
cargo build --release
alias up-vs="/xxx/target/release/update-vscode"