Rust 標準ライブラリにおける主要な型:時間、環境、およびプロセス
Rustの標準ライブラリ(std)には、オペレーティングシステムとのやり取りに必要なコア型――時間計測、環境変数、プロセス管理、パス操作など――が用意されています。これらの型を習得することで、Rustプログラムはシステムと真の意味で通信できるようになります。
Rust言語そのものが「エンジン」だとすれば、標準ライブラリは「ハンドル、ダッシュボード、そしてナビゲーションシステム」に相当します。標準ライブラリがなければ、プログラムで実行できるのは基本的な演算(加算、減算、乗算、除算、文字列の連結)だけになります。標準ライブラリがあれば、プログラムは現在の時刻を取得したり、コマンドライン引数を読み込んだり、外部コマンドを実行したり、ファイルパスを操作したりできるようになり、真の「アプリケーション」となります。
1. 学習内容
std::time::Durationおよびstd::time::Instant—時間間隔の測定とプログラムのタイミングstd::time::SystemTime—オペレーティングシステムの時刻の取得std::env::args—コマンドライン引数を読み込むstd::env::var—環境変数の読み取りと設定std::process::Command—外部コマンドを実行し、その出力を取得するstd::path::PathおよびPathBuf— クロスプラットフォームのパス操作
2. 定期バックアップスクリプトの経緯
(1) 悩み:手動バックアップの煩わしさ
トムは運用エンジニアで、毎日退勤前にサーバーから重要なデータを手作業でバックアップしなければならない。この作業は彼にとって本当に頭痛の種だ:
- 彼はサーバーにログインし、手動で
tarコマンドを入力しなければならない - バックアップファイル名には日付を含めること――
backup_20260703.tar.gz――彼はよくこれを間違えて入力してしまう。 - バックアップのパスは環境変数に保存されていますが、毎回
echo $BACKUP_PATHを使って確認しなければなりません - 彼は自動化スクリプトを書きたいと思っているが、プログラムがどれくらい実行されているのかがわからない。
- パス区切り文字はオペレーティングシステムによって異なります。Windowsでは
\が使用され、Linuxでは/が使用されます。
「もし、現在の時刻を自動的に取得し、環境変数からバックアップのパスを読み取り、圧縮コマンドを実行し、処理時間をログに記録するRustプログラムを書けるなら……それこそ理想的だ。」
(2) Rust標準ライブラリのアプローチ
use std::time::{Instant, SystemTime, UNIX_EPOCH};
use std::env;
use std::process::Command;
fn main() {
let start = Instant::now();
println!("=== Scheduled Backup Script ===");
// 1. Get the current system time
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs();
println!("[Time] Currently Unix Timestamp: {}s", now);
// 2. Read Environment Variables
let backup_dir = env::var("BACKUP_DIR")
.unwrap_or_else(|_| String::from("./backup"));
let db_name = env::var("DB_NAME")
.unwrap_or_else(|_| String::from("my_database"));
println!("[Layout] Backup Directory: {}", backup_dir);
println!("[Layout] Database Name: {}", db_name);
// 3. Constructing Backup File Names
let archive_name = format!("{}/backup_{}.tar.gz", backup_dir, now);
// 4. Execute harmless external commands (Simulated Backup)
let output = Command::new("echo")
.arg(format!("Simulating backup of {} to {}", db_name, archive_name))
.output()
.expect("Command execution failed");
println!("[Execute] Command Output: {}", String::from_utf8_lossy(&output.stdout));
// 5. Computation time
let elapsed = start.elapsed();
println!("[Time taken] Operation time: {:?}", elapsed);
println!("=== Backup Complete ===");
}
30行にも満たないこのスクリプトは、Rust標準ライブラリの中核となる機能、すなわち
Instant経過時間の測定、SystemTimeシステム時刻の取得、env::var環境変数の読み取り、およびCommand外部コマンドの実行を実演しています。それぞれの機能は、オペレーティングシステムから情報を取得したり、オペレーティングシステムを制御したりするための「窓口」としての役割を果たしています。
3. 基本概念
(1) 標準ライブラリに含まれるキー型システム
graph TB
A[Rust Key Types in the Standard Library] --> B[Time-related]
A --> C[Environment-Related]
A --> D[Process-Related]
A --> E[Path-related]
B --> B1["Duration: Time Period"]
B --> B2["Instant: Instant Timing"]
B --> B3["SystemTime: System Clock"]
C --> C1["env::args(): Command-Line Arguments"]
C --> C2["env::var(): Environment Variables"]
C --> C3["env::set_var(): Set a variable"]
D --> D1["Command::new"]
D --> D2["status() / output()"]
D --> D3["stdin / stdout / stderr"]
E --> E1["Path: Immutable Path Slices"]
E --> E2["PathBuf: Paths to Growth"]
E --> E3["join / parent / exists"]
(2) キータイプの比較
| タイプ/機能 | モジュール | 目的 | 主なメソッド |
|---|---|---|---|
Duration |
std::time |
時間間隔(例:5秒、100ミリ秒) | from_secs、from_millis、as_secs |
Instant |
std::time |
プログラム起動からの単調タイマー | now, elapsed, duration_since |
SystemTime |
std::time |
システムクロックの時刻(NTPで調整可能) | now, duration_since, UNIX_EPOCH |
env::args |
std::env |
コマンドライン引数を読み込む | Args イテレータを返す |
env::var |
std::env |
環境変数の読み取り | Result<String, VarError> に戻る |
Command std::process 外部コマンドの実行 new, arg, output, status |
|||
PathBuf |
std::path |
カスタマイズ可能なファイルパス | push, pop, set_extension |
| 不変のパス参照 |
(3) Path と PathBuf の関係
Path |
PathBuf |
|
|---|---|---|
| 文字列のような型 | &str (不変参照) |
String (所有権) |
| 可変性 | 不変(読み取り専用操作) | 可変(push、pop など) |
| メモリ位置 | スタックまたはヒープ上の参照 | ヒープ上のバッファ |
| 一般的な操作 | exists, is_dir, parent, join |
push, pop, set_extension |
| 変換 | path.to_path_buf() → PathBuf |
path_buf.as_path() → &Path |
(4) 時間タイプの比較に関するクイックリファレンス
| 種類 | 目的 | 単調増加 | 精度 | システムによる調整が可能 | 代表的な用途 |
|---|---|---|---|---|---|
Instant |
プログラム内でのタイミング測定 | はい | ナノ秒 | いいえ | コードの実行時間の測定 |
SystemTime |
システムクロックの時刻 | いいえ | ナノ秒 | はい(NTPなど) | 現在の日付と時刻を取得 |
Duration |
期間/間隔 | 該当なし | ナノ秒 | 該当なし | タイムアウト、スリープ、算術演算 |
PathとPathBufの関係は、&strとStringの関係とまったく同じです。つまり、PathBufは所有権を持つ可変パスであり、Pathは借用された不変のパススライスです。すべてのパス操作(join、parentなど)はPath上で定義されています。
4. 標準ライブラリにおけるキー型の例
(1) ▶ サンプル:時間の測定――持続時間、瞬間、および SystemTime(難易度 ⭐)
// ============================================
// Demo: The Three Time Types in the std::time Module
// Simulation: Program Timer and System Clock
// ============================================
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
fn main() {
println!("=== Time Type Demonstration ===\n");
// --- 1. Duration: Time Period ---
let five_secs = Duration::from_secs(5);
let hundred_ms = Duration::from_millis(100);
let two_mins = Duration::from_secs(2 * 60);
println!("[Duration] 5 seconds = {:?}", five_secs);
println!("[Duration] 100ms = {:?}", hundred_ms);
println!("[Duration] 2 minutes = {:?}", two_mins);
// Duration Operations: Addition, Subtraction, and Comparison
let total = five_secs + hundred_ms;
println!("[Duration] 5 seconds+100ms = {:?}", total);
println!("[Duration] 5 seconds > 100ms = {}", five_secs > hundred_ms);
// --- 2. Instant: Program Timer ---
let start = Instant::now();
// Simulate some time-consuming operations
let mut sum: u64 = 0;
for i in 0..1_000_000 {
sum = sum.wrapping_add(i);
}
let elapsed = start.elapsed();
println!("\n[Instant] Calculation sum={} Time taken: {:?}", sum, elapsed);
println!("[Instant] Takes milliseconds: {}ms", elapsed.as_millis());
println!("[Instant] Takes microseconds: {}µs", elapsed.as_micros());
// --- 3. SystemTime: System Time ---
let now = SystemTime::now();
let since_epoch = now.duration_since(UNIX_EPOCH).unwrap();
println!("\n[SystemTime] Current timestamp: {} seconds", since_epoch.as_secs());
println!("[SystemTime] Current timestamp: {} milliseconds", since_epoch.as_millis());
// Calculate the time one day ago
let one_day_ago = now - Duration::from_secs(24 * 60 * 60);
let since_epoch_ago = one_day_ago.duration_since(UNIX_EPOCH).unwrap();
println!("[SystemTime] Timestamp from one day ago: {} seconds", since_epoch_ago.as_secs());
println!("\n=== The time demonstration has ended ===");
}
出力:
=== Time Type Demonstration ===
[Duration] 5 seconds = 5s
[Duration] 100ms = 100ms
[Duration] 2 minutes = 120s
[Duration] 5 seconds+100ms = 5.1s
[Duration] 5 seconds > 100ms = true
[Instant] Calculation sum=499999500000 Time taken: 2.345ms
[Instant] Takes milliseconds: 2ms
[Instant] Takes microseconds: 2345µs
[SystemTime] Current timestamp: 1783012250 seconds
[SystemTime] Current timestamp: 1783012250123 milliseconds
[SystemTime] Timestamp from one day ago: 1782925850 seconds
=== The time demonstration has ended ===
Durationは時間間隔(例:「5 秒」)を表し、加算、減算、比較演算に対応しています。Instantは「プログラム起動からの単調タイマー」であり、システム時刻の調整の影響を受けないため、コードの実行時間の測定に適しています。SystemTimeはシステムクロック(NTPによって調整可能)を読み取り、現在の日時を取得するのに適しています。duration_since(UNIX_EPOCH)はUnixタイムスタンプを取得します。
(2) ▶ サンプル:環境変数とコマンドライン引数 — env::args と env::var (難易度 ⭐⭐)
// ============================================
// Demo: std::env Module for reading command-line arguments and environment variables
// Simulation: A configurable backup tool
// ============================================
use std::env;
fn main() {
println!("=== Environment and Parameter Explorer ===\n");
// --- 1. Reading Command-Line Arguments ---
let args: Vec<String> = env::args().collect();
println!("[args] Number of command-line arguments: {}", args.len());
if args.len() > 1 {
println!("[args] Program Name: {}", args[0]);
println!("[args] Input Parameters:");
for (i, arg) in args.iter().enumerate().skip(1) {
println!(" args[{}] = {}", i, arg);
}
} else {
println!("[args] No additional parameters were passed");
println!("[args] Presentation: The operating procedure is as follows");
println!(" cargo run -- --mode=backup --target=./data");
}
// --- 2. Read Environment Variables ---
println!("\n--- Environment Variable Detection ---");
// Try reading a few common environment variables
check_env_var("PATH");
check_env_var("HOME");
check_env_var("USER");
check_env_var("BACKUP_DIR"); // It may not exist.
check_env_var("DB_CONNECTION"); // It may not exist.
// --- 3. Read and Parse Custom Configuration ---
println!("\n--- Layout Analysis ---");
// Set an environment variable for demonstration purposes (Valid only within the current process)
// Note: Use set_var with caution in actual projects, it will affect the current process
env::set_var("MY_APP_MODE", "backup");
env::set_var("MY_APP_VERBOSE", "true");
let mode = env::var("MY_APP_MODE").unwrap_or_else(|_| "default".to_string());
let verbose = env::var("MY_APP_VERBOSE")
.map(|v| v == "true" || v == "1")
.unwrap_or(false);
println!("[Layout] Operating Mode: {}", mode);
println!("[Layout] Detailed Output: {}", verbose);
// --- 4. Iterate through all environment variables (Show only the first few) ---
println!("\n--- List of Environment Variables(first 5)---");
for (i, (key, value)) in env::vars().enumerate().take(5) {
println!(" {} = {}", key, value);
}
println!("\n=== Survey Complete ===");
}
/// Try reading the environment variables and printing them
fn check_env_var(name: &str) {
match env::var(name) {
Ok(val) => println!("[env] {} = {}", name, val),
Err(env::VarError::NotPresent) => println!("[env] {} = (Not set)", name),
Err(env::VarError::NotUnicode(_)) => println!("[env] {} = (non-UTF-8 value)", name),
}
}
出力:
=== Environment and Parameter Explorer ===
[args] Number of command-line arguments: 1
[args] No additional parameters were passed
[args] Presentation: The operating procedure is as follows
cargo run -- --mode=backup --target=./data
--- Environment Variable Detection ---
[env] PATH = C:\Windows\system32;C:\Windows;...
[env] HOME = (Not set)
[env] USER = (Not set)
[env] BACKUP_DIR = (Not set)
[env] DB_CONNECTION = (Not set)
--- Layout Analysis ---
[Layout] Operating Mode: backup
[Layout] Detailed Output: true
--- List of Environment Variables(first 5)---
ALLUSERSPROFILE = C:\ProgramData
APPDATA = C:\Users\Administrator\AppData\Roaming
...
=== Survey Complete ===
env::args()コマンドライン引数を巡回するイテレータを返します。最初の要素はプログラムのパスです。env::var(name)環境変数を読み取り、Result<String, VarError>を返します。変数が存在しない場合 (NotPresent) や、値が有効な Unicode ではない場合 (NotUnicode) は、この処理が失敗する可能性があります。env::set_var環境変数を設定します(現在のプロセスでのみ有効です)。env::vars()すべての環境変数を順に処理します。
(3) ▶ サンプル:コマンドとパス—外部コマンドの実行とパス操作(難易度 ⭐⭐)
// ============================================
// Demo: std::process::Command and std::path::Path/PathBuf
// Simulation:Backup Script——Build Path、Execute the compression command
// ============================================
use std::path::{Path, PathBuf};
use std::process::Command;
fn main() {
println!("=== Demonstration of Path Operations and External Commands ===\n");
// --- 1. Path and PathBuf Basic Operations ---
println!("--- Path Operations ---");
// Create PathBuf (Variable Paths with Ownership)
let mut backup_dir = PathBuf::new();
backup_dir.push("data");
backup_dir.push("backups");
println!("[PathBuf] Initial Path: {}", backup_dir.display());
// Set File Extensions
let mut archive = backup_dir.clone();
archive.push("database");
archive.set_extension("tar.gz");
println!("[PathBuf] Archived Files: {}", archive.display());
// Path Read-only operations
let path = Path::new("C:/Users/Alice/Documents/report.pdf");
println!("\n[Path] File Path: {}", path.display());
println!("[Path] File Name: {:?}", path.file_name());
println!("[Path] File extension: {:?}", path.extension());
println!("[Path] Parent directory: {:?}", path.parent());
println!("[Path] Does it exist?: {}", path.exists());
// Path Concatenation
let docs = Path::new("./docs");
let full_path = docs.join("rust").join("guide.md");
println!("[Path] Path Concatenation: {}", full_path.display());
// --- 2. Usage Command Execute an external command ---
println!("\n--- Executing External Commands ---");
// Example A: Execute "echo" Command (Harmless Command)
let echo_result = Command::new("echo")
.arg("Hello from Rust! Backup process started.")
.output()
.expect("echo Command execution failed");
println!("[Command] echo Output: {}",
String::from_utf8_lossy(&echo_result.stdout));
// Example B: Execute "whoami" Command (Show Current User)
let whoami_output = Command::new("whoami")
.output()
.expect("whoami Command execution failed");
if whoami_output.status.success() {
let username = String::from_utf8_lossy(&whoami_output.stdout);
println!("[Command] Current User: {}", username.trim());
} else {
let err = String::from_utf8_lossy(&whoami_output.stderr);
println!("[Command] whoami Failure: {}", err);
}
// Example C: Check whether the command was successful (status Pattern)
let status = Command::new("cmd")
.args(["/C", "dir", "./"])
.status()
.expect("dir Command execution failed");
if status.success() {
println!("[Command] dir The command was executed successfully (exit code: {})", status.code().unwrap_or(-1));
} else {
println!("[Command] dir Command execution failed (exit code: {:?})", status.code());
}
// --- 3. Combined Use: Build Command Based on Path ---
println!("\n--- Simulate the Backup Process ---");
let source = Path::new("./data/documents");
let dest = Path::new("./backup/documents_backup.tar.gz");
println!("Backup Source: {}", source.display());
println!("Backup Destination: {}", dest.display());
// Simulation tar Command (This will not actually be executed, just demonstrating command construction)
let _mock_cmd = Command::new("tar")
.arg("-czf")
.arg(dest)
.arg(source)
.status();
// Actually executing a harmless display command
let show_cmd = Command::new("echo")
.arg(format!(
"Would execute: tar -czf {} {}",
dest.display(),
source.display()
))
.output()
.unwrap();
println!("Simulation Commands: {}",
String::from_utf8_lossy(&show_cmd.stdout).trim());
println!("\n=== End of Presentation ===");
}
出力:
=== Demonstration of Path Operations and External Commands ===
--- Path Operations ---
[PathBuf] Initial Path: data\backups
[PathBuf] Archived Files: data\backups\database.tar.gz
[Path] File Path: C:/Users/Alice/Documents/report.pdf
[Path] File Name: Some("report.pdf")
[Path] File extension: Some("pdf")
[Path] Parent directory: Some("C:/Users/Alice/Documents")
[Path] Does it exist?: false
[Path] Path Concatenation: docs\rust\guide.md
--- Executing External Commands ---
[Command] echo Output: Hello from Rust! Backup process started.
[Command] Current User: DESKTOP-ABC123\Administrator
[Command] dir The command was executed successfully (exit code: 0)
--- Simulate the Backup Process ---
Backup Source: ./data/documents
Backup Destination: ./backup/documents_backup.tar.gz
Simulation Commands: Would execute: tar -czf ./backup/documents_backup.tar.gz ./data/documents
=== End of Presentation ===
Command::new("program name")は新しいコマンドを作成します。パラメータはargおよびargsを使用して追加されます。output()は stdout および stderr をキャプチャします(出力処理が必要なシナリオに適しています)。一方、status()は終了コードのみを確認します(出力が不要なシナリオに適しています)。Path::display()は、クロスプラットフォームな形式でパスを表示します。PathBufはPathの可変バージョンであり、push、pop、set_extensionなどの変更操作をサポートしています。path.join(...)は新しいPathBufを返します。
(4) ▶ サンプル:総合演習 — CLI ツール:ファイル情報ビューア(難易度 ⭐⭐⭐)
// ============================================
// Comprehensive Example: std::fs + std::path + std::time
// ============================================
use std::env;
use std::fs;
use std::path::Path;
use std::time::SystemTime;
fn format_size(size: u64) -> String {
const KB: u64 = 1024;
const MB: u64 = 1024 * KB;
const GB: u64 = 1024 * MB;
if size >= GB { format!("{:.2} GB", size as f64 / GB as f64) }
else if size >= MB { format!("{:.2} MB", size as f64 / MB as f64) }
else if size >= KB { format!("{:.2} KB", size as f64 / KB as f64) }
else { format!("{} B", size) }
}
fn format_time(systime: SystemTime) -> String {
let duration = systime.duration_since(SystemTime::UNIX_EPOCH).unwrap_or_default();
let secs = duration.as_secs();
let days = secs / 86400;
let hours = (secs % 86400) / 3600;
let minutes = (secs % 3600) / 60;
format!("{} days {:02}:{:02} UTC", days, hours, minutes)
}
fn inspect_file(path_str: &str) -> Result<(), Box<dyn std::error::Error>> {
let path = Path::new(path_str);
if !path.exists() {
println!("The path does not exist: {}", path.display());
return Ok(());
}
println!("=== File Information ===");
println!("Path: {}", path.display());
println!("File Name: {:?}", path.file_name());
println!("File extension: {:?}", path.extension());
println!("Parent directory: {:?}", path.parent());
if path.is_file() {
let metadata = fs::metadata(path)?;
println!("Size: {}", format_size(metadata.len()));
println!("Read-only: {}", metadata.permissions().readonly());
println!("Last Modified: {}", format_time(metadata.modified()?));
} else if path.is_dir() {
println!("Type: Table of Contents");
let entries: Vec<_> = fs::read_dir(path)?
.filter_map(|e| e.ok())
.collect();
println!("Number of entries: {}", entries.len());
for entry in entries.iter().take(10) {
let name = entry.file_name().to_string_lossy().to_string();
let tag = if entry.path().is_dir() { "DIR" } else { "FILE" };
println!(" [{}] {}", tag, name);
}
if entries.len() > 10 {
println!(" ... And also {} entries", entries.len() - 10);
}
}
Ok(())
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let args: Vec<String> = env::args().collect();
let target = if args.len() > 1 { &args[1] } else { "." };
inspect_file(target)
}
出力(cargo run -- src/main.rsの実行):
=== File Information ===
Path: src/main.rs
File Name: Some("main.rs")
File extension: Some("rs")
Parent directory: Some("src")
Size: 1.23 KB
Read-only: false
Last Modified: 20504 days 08:30 UTC
この例では、
std::fs(ファイルのメタデータ)、std::path(パスの操作)、std::time(時刻の書式設定)、およびstd::env(コマンドライン引数)を組み合わせて使用しています。format_sizeはファイルサイズをわかりやすい形式で表示し、format_timeはSystemTimeを読みやすい時刻形式に変換します。
(5) ▶ サンプル:総合演習—シンプルなタイマーとシステム情報(難易度 ⭐⭐)
// ============================================
// Comprehensive Example: std::time + std::env + std::process
// ============================================
use std::env;
use std::process::Command;
use std::time::{Duration, Instant};
struct Timer {
start: Instant,
label: String,
}
impl Timer {
fn new(label: &str) -> Self {
println!("[{}] The timer starts", label);
Timer { start: Instant::now(), label: label.to_string() }
}
fn elapsed(&self) -> Duration {
self.start.elapsed()
}
fn stop(self) -> Duration {
let elapsed = self.elapsed();
println!("[{}] Time's up: {:.3}s", self.label, elapsed.as_secs_f64());
elapsed
}
}
fn main() {
println!("=== System Information ===");
println!("Current Directory: {:?}", env::current_dir().unwrap_or_default());
println!("Operating System: {}", env::consts::OS);
println!("Architecture: {}", env::consts::ARCH);
println!("\n=== Environment Variables ===");
for key in &["HOME", "PATH", "USER", "LANG"] {
match env::var(key) {
Ok(val) => println!("{}: {} Character", key, val.len()),
Err(_) => println!("{}: (Not set)", key),
}
}
println!("\n=== Timed Demonstration ===");
let t1 = Timer::new("Calculating the Fibonacci Sequence");
let mut fib: Vec<u64> = vec![0, 1];
for _ in 0..45 {
let next = fib[fib.len()-1] + fib[fib.len()-2];
fib.push(next);
}
t1.stop();
println!("fib(45) = {}", fib[45]);
let t2 = Timer::new("String Operations");
let mut s = String::new();
for i in 0..10_000 {
s.push_str(&format!("item{} ", i));
}
let len = s.len();
t2.stop();
println!("String Length: {} Character", len);
println!("\n=== Process Exit Code ===");
let status = Command::new("cmd")
.args(&["/C", "echo", "hello"])
.status();
match status {
Ok(s) => println!("Exit Code: {}", s.code().unwrap_or(-1)),
Err(e) => println!("Execution Failed: {}", e),
}
}
出力:
=== System Information ===
Current Directory: "G:\\..."
Operating System: windows
Architecture: x86_64
=== Environment Variables ===
HOME: 20 Character
PATH: 500 Character
...
=== Timed Demonstration ===
[Calculating the Fibonacci Sequence] The timer starts
[Calculating the Fibonacci Sequence] Time's up: X.XXXs
fib(45) = 1134903170
[String Operations] The timer starts
[String Operations] Time's up: X.XXXs
String Length: 88889 Character
=== Process Exit Code ===
Exit Code: 0
TimerはInstantの RAII パターンを使用して時間を自動的に追跡します。env::constsはプラットフォーム情報を取得します。env::varは環境変数を読み取ります。Commandは外部コマンドを実行し、終了コードを取得します。
❓ よくある質問
Instant と SystemTime の違いは何ですか?それぞれどのような場合に使用すべきですか?Instant は単調増加するタイマーであるのに対し、SystemTime はシステムクロックを読み取ります。env::var および env::args が返す文字列のエンコーディングは何ですか?String です。Command::output() と Command::status() の違いは何ですか?output() は標準出力(stdout)と標準エラー出力(stderr)を取得しますが、status() は終了コードのみを確認します。Path と PathBuf はクロスプラットフォームであり、内部ではプラットフォーム固有のパス区切り文字を使用しています。Command を使用してコマンドを実行する場合、PATH 環境変数は自動的に検索されますか?Command::new("program name") は PATH 環境変数を検索します。📖 まとめ
Durationは時間間隔(秒、ミリ秒、マイクロ秒)を表し、加算、減算、比較演算に対応しています。Instantは単調タイマーであり、経過時間の測定に適しています。SystemTimeはシステムクロックを読み取り、タイムスタンプの取得に適していますenv::args()コマンドライン引数のイテレータを返します。最初の要素はプログラムのパスです。env::var(name)環境変数を読み取り、Result<String, VarError>を返します。env::set_var環境変数を設定する(現在のプロセスでのみ有効)。本番環境では注意して使用すること。env::vars()すべての環境変数を順に処理するCommand::new外部コマンドを実行する;arg/argsパラメータを追加する;output()出力を取得する;status()終了コードを確認するPathBufは、所有権を持つ可変パス(Stringと同様)であり、push、pop、set_extensionなどの変更に対応しています。Pathは、&strと同様の借用された不変のパススライスであり、exists、parent、join、およびfile_nameなどの読み取り専用操作をサポートしています。
📝 練習問題
- 難易度 ⭐:
Instantを使用してループの実行時間(1 から 1,000,000 までカウント)を測定し、経過時間をミリ秒(ms)とマイクロ秒(µs)でそれぞれ出力するプログラムを作成してください。また、SystemTimeを使用して、プログラムの開始時の Unix タイムスタンプを取得し、それを表示してください。 - 難易度 ⭐⭐:「環境変数ビューア」を実装してください。このプログラムは、コマンドライン引数で指定された環境変数の値を読み取り、出力する必要があります。その変数が存在しない場合は、わかりやすいメッセージを表示してください。追加機能:引数が指定されていない場合は、
MY_またはRUST_で始まるすべての環境変数とその値を一覧表示してください。 - 難易度 ⭐⭐⭐:「シンプルなバックアップツール」を実装してください。
PathBufを使用して、ソースディレクトリと保存先のアーカイブパスを構築してください。環境変数BACKUP_SOURCEおよびBACKUP_DESTを通じて設定を読み込みます(設定されていない場合は、デフォルト値./dataおよび./backup/archive.tar.gzを使用します)。Commandを使用してechoコマンドを実行し、バックアッププロセスをシミュレートします。「[source] を [dest] にバックアップ中」と出力してください。Instantを使用して、開始時と終了時の合計経過時間を記録し、出力してください。ソースディレクトリが存在するかどうかを確認するには、Pathのexists()を使用する必要があります。



