1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983
//! 检查和操作进程的环境。
//!
//! 该模块包含用于检查各个方面的函数,例如环境变量,进程参数,当前目录以及各种其他重要目录。
//!
//!
//! 该模块中有几个函数和结构体,它们的对应部分以 `os` 结尾。
//! 以 `os` 结尾的那些将返回 [`OsString`],而没有以 `os` 结尾的那些将返回 [`String`]。
//!
//!
#![stable(feature = "env", since = "1.0.0")]
#[cfg(test)]
mod tests;
use crate::error::Error;
use crate::ffi::{OsStr, OsString};
use crate::fmt;
use crate::io;
use crate::path::{Path, PathBuf};
use crate::sys;
use crate::sys::os as os_imp;
/// 返回当前的工作目录为 [`PathBuf`]。
///
/// # 特定于平台的行为
///
/// 这个函数 [currently] 对应于 Unix 上的 `getcwd` 函数和 Windows 上的 `GetCurrentDirectoryW` 函数。
///
///
/// [currently]: crate::io#platform-specific-behavior
///
/// # Errors
///
/// 如果当前工作目录值无效,则返回 [`Err`]。
/// 可能的情况:
///
/// * 当前目录不存在。
/// * 没有足够的权限来访问当前目录。
///
/// # Examples
///
/// ```
/// use std::env;
///
/// fn main() -> std::io::Result<()> {
/// let path = env::current_dir()?;
/// println!("The current directory is {}", path.display());
/// Ok(())
/// }
/// ```
#[doc(alias = "pwd")]
#[doc(alias = "getcwd")]
#[doc(alias = "GetCurrentDirectory")]
#[stable(feature = "env", since = "1.0.0")]
pub fn current_dir() -> io::Result<PathBuf> {
os_imp::getcwd()
}
/// 将当前工作目录更改为指定的路径。
///
/// # 特定于平台的行为
///
/// 这个函数 [currently] 对应于 Unix 上的 `chdir` 函数和 Windows 上的 `SetCurrentDirectoryW` 函数。
///
///
/// 如果操作失败,则返回 [`Err`]。
///
/// [currently]: crate::io#platform-specific-behavior
///
/// # Examples
///
/// ```
/// use std::env;
/// use std::path::Path;
///
/// let root = Path::new("/");
/// assert!(env::set_current_dir(&root).is_ok());
/// println!("Successfully changed working directory to {}!", root.display());
/// ```
#[doc(alias = "chdir")]
#[stable(feature = "env", since = "1.0.0")]
pub fn set_current_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
os_imp::chdir(path.as_ref())
}
/// 在此进程的环境变量的快照上进行迭代的迭代器。
///
/// 该结构体由 [`env::vars()`] 创建。有关更多信息,请参见其文档。
///
/// [`env::vars()`]: vars
#[stable(feature = "env", since = "1.0.0")]
pub struct Vars {
inner: VarsOs,
}
/// 在此进程的环境变量的快照上进行迭代的迭代器。
///
/// 该结构体由 [`env::vars_os()`] 创建。有关更多信息,请参见其文档。
///
/// [`env::vars_os()`]: vars_os
#[stable(feature = "env", since = "1.0.0")]
pub struct VarsOs {
inner: os_imp::Env,
}
/// 返回当前进程的所有环境变量的字符串 (变量,值) 对的迭代器。
///
///
/// 返回的迭代器包含此调用时进程环境变量的快照。
/// 之后对环境变量的修改将不会反映在返回的迭代器中。
///
/// # Panics
///
/// 进行迭代时,如果环境中的任何键或值不是有效的 unicode,则返回的迭代器将为 panic。
/// 如果不希望这样做,请考虑使用 [`env::vars_os()`]。
///
/// # Examples
///
/// ```
/// use std::env;
///
/// // 我们将通过引用迭代到 env::vars () ; 返回的元素。
/////
/// for (key, value) in env::vars() {
/// println!("{key}: {value}");
/// }
/// ```
///
/// [`env::vars_os()`]: vars_os
///
///
#[must_use]
#[stable(feature = "env", since = "1.0.0")]
pub fn vars() -> Vars {
Vars { inner: vars_os() }
}
/// 对于当前进程的所有环境变量,返回 OS 字符串对 (变量,值) 对的迭代器。
///
///
/// 返回的迭代器包含此调用时进程环境变量的快照。
/// 之后对环境变量的修改将不会反映在返回的迭代器中。
///
/// 请注意,返回的迭代器不会检查环境变量是否为有效的 Unicode。
/// 如果您想在无效的 UTF-8 上使用 panic,请改用 [`vars`] 函数。
///
/// # Examples
///
/// ```
/// use std::env;
///
/// // 我们将通过引用迭代到 env::vars_os () ; 返回的元素。
/////
/// for (key, value) in env::vars_os() {
/// println!("{key:?}: {value:?}");
/// }
/// ```
///
///
#[must_use]
#[stable(feature = "env", since = "1.0.0")]
pub fn vars_os() -> VarsOs {
VarsOs { inner: os_imp::env() }
}
#[stable(feature = "env", since = "1.0.0")]
impl Iterator for Vars {
type Item = (String, String);
fn next(&mut self) -> Option<(String, String)> {
self.inner.next().map(|(a, b)| (a.into_string().unwrap(), b.into_string().unwrap()))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for Vars {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Vars").finish_non_exhaustive()
}
}
#[stable(feature = "env", since = "1.0.0")]
impl Iterator for VarsOs {
type Item = (OsString, OsString);
fn next(&mut self) -> Option<(OsString, OsString)> {
self.inner.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for VarsOs {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("VarOs").finish_non_exhaustive()
}
}
/// 从当前进程中获取环境变量 `key`。
///
/// # Errors
///
/// 如果未设置环境变量,此函数将返回错误。
///
/// 如果环境变量的名称包含等号字符 (`=`) 或 NUL 字符,此函数可能会返回错误。
///
///
/// 如果环境变量的值不是有效的 Unicode,此函数将返回错误。
/// 如果不需要,请考虑使用 [`var_os`]。
///
/// # Examples
///
/// ```
/// use std::env;
///
/// let key = "HOME";
/// match env::var(key) {
/// Ok(val) => println!("{key}: {val:?}"),
/// Err(e) => println!("couldn't interpret {key}: {e}"),
/// }
/// ```
#[stable(feature = "env", since = "1.0.0")]
pub fn var<K: AsRef<OsStr>>(key: K) -> Result<String, VarError> {
_var(key.as_ref())
}
fn _var(key: &OsStr) -> Result<String, VarError> {
match var_os(key) {
Some(s) => s.into_string().map_err(VarError::NotUnicode),
None => Err(VarError::NotPresent),
}
}
/// 从当前进程中获取环境变量 `key`,如果未设置变量或存在其他错误,则返回 [`None`]。
///
///
/// 如果环境变量的名称包含等号字符 (`=`) 或 NUL 字符,它可能会返回 `None`。
///
/// 请注意,此函数不会检查环境变量是否为有效的 Unicode。
/// 如果您想在无效的 UTF-8 上出错,请改用 [`var`] 函数。
///
/// # Examples
///
/// ```
/// use std::env;
///
/// let key = "HOME";
/// match env::var_os(key) {
/// Some(val) => println!("{key}: {val:?}"),
/// None => println!("{key} is not defined in the environment.")
/// }
/// ```
///
///
#[must_use]
#[stable(feature = "env", since = "1.0.0")]
pub fn var_os<K: AsRef<OsStr>>(key: K) -> Option<OsString> {
_var_os(key.as_ref())
}
fn _var_os(key: &OsStr) -> Option<OsString> {
os_imp::getenv(key)
}
/// 与环境变量交互的操作的错误类型。
/// 可能是从 [`env::var()`] 返回的。
///
/// [`env::var()`]: var
#[derive(Debug, PartialEq, Eq, Clone)]
#[stable(feature = "env", since = "1.0.0")]
pub enum VarError {
/// 当前进程的环境中不存在指定的环境变量。
///
#[stable(feature = "env", since = "1.0.0")]
NotPresent,
/// 找到了指定的环境变量,但是它不包含有效的 unicode 数据。
/// 找到的数据作为该变体的有效载荷返回。
///
#[stable(feature = "env", since = "1.0.0")]
NotUnicode(#[stable(feature = "env", since = "1.0.0")] OsString),
}
#[stable(feature = "env", since = "1.0.0")]
impl fmt::Display for VarError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
VarError::NotPresent => write!(f, "environment variable not found"),
VarError::NotUnicode(ref s) => {
write!(f, "environment variable was not valid unicode: {:?}", s)
}
}
}
}
#[stable(feature = "env", since = "1.0.0")]
impl Error for VarError {
#[allow(deprecated)]
fn description(&self) -> &str {
match *self {
VarError::NotPresent => "environment variable not found",
VarError::NotUnicode(..) => "environment variable was not valid unicode",
}
}
}
/// 将环境变量 `key` 设置为当前正在运行的进程的值 `value`。
///
/// 请注意,虽然在 Rust 中对环境变量进行并发访问是安全的,但某些平台仅公开本质上不安全的非线程安全 API 来检查环境。
/// 因此,在审核对不安全的外部 FFI 函数的调用时,需要格外小心,以确保所有外部环境访问均与 Rust 中的访问正确同步。
///
///
/// 有关 Unix 上这种不安全性的讨论,请参见:
///
/// - [Austin Group Bugzilla](https://austingroupbugs.net/view.php?id=188)
/// - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=15607#c2)
///
/// # Panics
///
/// 如果 `key` 为空,包含 ASCII 等号 `'='` 或 NUL 字符 `'\0'`,或者当 `value` 包含 NUL 字符时,此函数可能 panic。
///
/// # Examples
///
/// ```
/// use std::env;
///
/// let key = "KEY";
/// env::set_var(key, "VALUE");
/// assert_eq!(env::var(key), Ok("VALUE".to_string()));
/// ```
///
///
///
///
#[stable(feature = "env", since = "1.0.0")]
pub fn set_var<K: AsRef<OsStr>, V: AsRef<OsStr>>(key: K, value: V) {
_set_var(key.as_ref(), value.as_ref())
}
fn _set_var(key: &OsStr, value: &OsStr) {
os_imp::setenv(key, value).unwrap_or_else(|e| {
panic!("failed to set environment variable `{key:?}` to `{value:?}`: {e}")
})
}
/// 从当前正在运行的进程的环境中删除环境变量。
///
/// 请注意,虽然在 Rust 中对环境变量进行并发访问是安全的,但某些平台仅公开本质上不安全的非线程安全 API 来检查环境。
/// 因此,在审核对不安全的外部 FFI 函数的调用时,需要格外小心,以确保所有外部环境访问都与 Rust 中的访问正确同步。
///
///
/// 有关 Unix 上这种不安全性的讨论,请参见:
///
/// - [Austin Group Bugzilla](https://austingroupbugs.net/view.php?id=188)
/// - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=15607#c2)
///
/// # Panics
///
/// 如果 `key` 为空,包含 ASCII 等于 `'='` 或 NUL 字符 `'\0'` 或值包含 NUL 字符,则此函数可能为 panic。
///
/// # Examples
///
/// ```
/// use std::env;
///
/// let key = "KEY";
/// env::set_var(key, "VALUE");
/// assert_eq!(env::var(key), Ok("VALUE".to_string()));
///
/// env::remove_var(key);
/// assert!(env::var(key).is_err());
/// ```
///
///
///
///
#[stable(feature = "env", since = "1.0.0")]
pub fn remove_var<K: AsRef<OsStr>>(key: K) {
_remove_var(key.as_ref())
}
fn _remove_var(key: &OsStr) {
os_imp::unsetenv(key)
.unwrap_or_else(|e| panic!("failed to remove environment variable `{key:?}`: {e}"))
}
/// 一个迭代器,该迭代器根据特定于平台的约定将环境变量拆分为路径。
///
///
/// 迭代器元素类型为 [`PathBuf`]。
///
/// 该结构体由 [`env::split_paths()`] 创建。有关更多信息,请参见其文档。
///
/// [`env::split_paths()`]: split_paths
///
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "env", since = "1.0.0")]
pub struct SplitPaths<'a> {
inner: os_imp::SplitPaths<'a>,
}
/// 根据平台约定对 `PATH` 环境变量解析输入。
///
///
/// 返回 `unparsed` 中包含的路径上的迭代器。
/// 迭代器元素类型为 [`PathBuf`]。
///
/// # Examples
///
/// ```
/// use std::env;
///
/// let key = "PATH";
/// match env::var_os(key) {
/// Some(paths) => {
/// for path in env::split_paths(&paths) {
/// println!("'{}'", path.display());
/// }
/// }
/// None => println!("{key} is not defined in the environment.")
/// }
/// ```
#[stable(feature = "env", since = "1.0.0")]
pub fn split_paths<T: AsRef<OsStr> + ?Sized>(unparsed: &T) -> SplitPaths<'_> {
SplitPaths { inner: os_imp::split_paths(unparsed.as_ref()) }
}
#[stable(feature = "env", since = "1.0.0")]
impl<'a> Iterator for SplitPaths<'a> {
type Item = PathBuf;
fn next(&mut self) -> Option<PathBuf> {
self.inner.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for SplitPaths<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SplitPaths").finish_non_exhaustive()
}
}
/// `PATH` 变量上的操作的错误类型。
/// 可能是从 [`env::join_paths()`] 返回的。
///
/// [`env::join_paths()`]: join_paths
#[derive(Debug)]
#[stable(feature = "env", since = "1.0.0")]
pub struct JoinPathsError {
inner: os_imp::JoinPathsError,
}
/// 为 `PATH` 环境变量适当地加入 [`Path`] 的集合。
///
/// # Errors
///
/// 如果输入 [`Path`] 之一包含用于构造 `PATH` 变量的无效字符 (Windows 上的双引号或 Unix 上的冒号),则返回 [`Err`] (包含错误消息)。
///
///
/// # Examples
///
/// 在类似 Unix 的平台上的连接路径:
///
/// ```
/// use std::env;
/// use std::ffi::OsString;
/// use std::path::Path;
///
/// fn main() -> Result<(), env::JoinPathsError> {
/// # if cfg!(unix) {
/// let paths = [Path::new("/bin"), Path::new("/usr/bin")];
/// let path_os_string = env::join_paths(paths.iter())?;
/// assert_eq!(path_os_string, OsString::from("/bin:/usr/bin"));
/// # }
/// Ok(())
/// }
/// ```
///
/// 在类似 Unix 的平台上加入包含冒号的路径会导致错误:
///
/// ```
/// # if cfg!(unix) {
/// use std::env;
/// use std::path::Path;
///
/// let paths = [Path::new("/bin"), Path::new("/usr/bi:n")];
/// assert!(env::join_paths(paths.iter()).is_err());
/// # }
/// ```
///
/// 将 `env::join_paths()` 与 [`env::split_paths()`] 结合使用,可以将项追加到 `PATH` 环境变量中:
///
/// ```
/// use std::env;
/// use std::path::PathBuf;
///
/// fn main() -> Result<(), env::JoinPathsError> {
/// if let Some(path) = env::var_os("PATH") {
/// let mut paths = env::split_paths(&path).collect::<Vec<_>>();
/// paths.push(PathBuf::from("/home/xyz/bin"));
/// let new_path = env::join_paths(paths)?;
/// env::set_var("PATH", &new_path);
/// }
///
/// Ok(())
/// }
/// ```
///
/// [`env::split_paths()`]: split_paths
///
///
///
///
#[stable(feature = "env", since = "1.0.0")]
pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
where
I: IntoIterator<Item = T>,
T: AsRef<OsStr>,
{
os_imp::join_paths(paths.into_iter()).map_err(|e| JoinPathsError { inner: e })
}
#[stable(feature = "env", since = "1.0.0")]
impl fmt::Display for JoinPathsError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.inner.fmt(f)
}
}
#[stable(feature = "env", since = "1.0.0")]
impl Error for JoinPathsError {
#[allow(deprecated, deprecated_in_future)]
fn description(&self) -> &str {
self.inner.description()
}
}
/// 返回当前用户主目录的路径 (如果已知)。
///
/// # Unix
///
/// - 返回 'HOME' 环境变量的值 (如果已设置) (包括一个空字符串)。
/// - 否则,它将尝试通过使用当前用户的 UID 调用 `getpwuid_r` 函数来确定主目录。
/// 从 `getpwuid_r` 函数返回的空主目录字段被视为有效值。
/// - 如果当前用户在 /etc/passwd 文件中没有条目,则返回 `None`。
///
/// # Windows
///
/// - 返回 'HOME' 环境变量的值 (如果已设置) (包括一个空字符串)。
/// - 否则,返回 'USERPROFILE' 环境变量的值 (如果已设置) (包括一个空字符串)。
/// - 如果两者都不存在,则使用 [`GetUserProfileDirectory`][msdn] 返回路径。
///
/// [msdn]: https://docs.microsoft.com/en-us/windows/win32/api/userenv/nf-userenv-getuserprofiledirectorya
///
/// # Deprecation
///
/// 此函数已弃用,因为 Windows 上的行为不正确。
/// 'HOME' 环境变量在 Windows 上不是标准的,可能不会产生预期的结果; 例如,在 Cygwin 或 Mingw 下,它会在应该返回 `C:\Users\you` 时返回 `/home/you`。
///
///
/// # Examples
///
/// ```
/// use std::env;
///
/// match env::home_dir() {
/// Some(path) => println!("Your home directory, probably: {}", path.display()),
/// None => println!("Impossible to get your home dir!"),
/// }
/// ```
///
///
///
///
///
#[deprecated(
since = "1.29.0",
note = "This function's behavior may be unexpected on Windows. \
Consider using a crate from crates.io instead."
)]
#[must_use]
#[stable(feature = "env", since = "1.0.0")]
pub fn home_dir() -> Option<PathBuf> {
os_imp::home_dir()
}
/// 返回临时目录的路径。
///
/// 临时目录可以在用户之间共享,也可以在具有不同权限的进程之间共享; 因此,在临时目录中创建任何文件或目录都必须使用安全方法来创建唯一命名的文件。
///
/// 使用固定或可预测的名称创建文件或目录可能会导致 "不安全的临时文件" 安全漏洞。
/// 考虑使用安全创建临时文件或目录的 crate。
///
/// # 特定于平台的行为
///
/// 在 Unix 上,如果设置了 `TMPDIR` 环境变量,则返回它的值,否则,对于非 Android 系统,将返回 `/tmp`。
/// 在 X01 上,因为没有为每个 X 分配临时文件夹 (通常是应用程序),所以它返回 `/data/local/tmp`。
/// 在 Windows 上,行为等同于 [`GetTempPath2`][GetTempPath2] / [`GetTempPath`][GetTempPath],这个函数在内部使用。
/// 注意,这个 [将来可能会改变][changes]。
///
/// [changes]: io#platform-specific-behavior
/// [GetTempPath2]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppath2a
/// [GetTempPath]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppatha
///
/// ```no_run
/// use std::env;
///
/// fn main() {
/// let dir = env::temp_dir();
/// println!("Temporary directory: {}", dir.display());
/// }
/// ```
///
///
///
///
///
#[must_use]
#[stable(feature = "env", since = "1.0.0")]
pub fn temp_dir() -> PathBuf {
os_imp::temp_dir()
}
/// 返回当前正在运行的可执行文件的完整文件系统路径。
///
/// # 特定于平台的行为
///
/// 如果可执行文件是通过符号链接调用的,则某些平台将返回符号链接的路径,而其他平台将返回符号链接目标的路径。
///
///
/// 如果可执行文件在运行时被重命名,平台可能会返回加载时的路径而不是新路径。
///
/// # Errors
///
/// 获取当前可执行文件的路径是特定于平台的操作,由于多种原因,该操作可能会失败。
/// 一些错误可能包括但不限于文件系统操作失败或常规 syscall 错误。
///
/// # Security
///
/// 这个函数的输出不应该被任何可能有安全隐患的东西信任。
/// 基本上,如果用户可以运行可执行文件,他们可以任意更改输出。
///
/// 例如,您可以很容易地引入一个竞态条件。它是这样的:
///
/// 1. 您可以使用 `current_exe()` 获取当前可执行文件的路径,并将其存储在一个变量中。
/// 2. 时间流逝。恶意行为者删除当前可执行文件,并将其替换为恶意文件。
/// 3. 然后,您使用存储的路径重新执行当前的可执行文件。
///
/// 您希望安全地执行当前的可执行文件,但您正在执行一些完全不同的东西。您刚刚执行的代码以您的权限运行。
///
/// 如果不正确使用会 [导致特权升级][lead to privilege escalation],这种行为是已知的。
///
/// [lead to privilege escalation]: https://securityvulns.com/Wdocument183.html
///
/// # Examples
///
/// ```
/// use std::env;
///
/// match env::current_exe() {
/// Ok(exe_path) => println!("Path of this executable is: {}",
/// exe_path.display()),
/// Err(e) => println!("failed to get current exe path: {e}"),
/// };
/// ```
///
///
///
///
///
///
///
///
///
///
///
#[stable(feature = "env", since = "1.0.0")]
pub fn current_exe() -> io::Result<PathBuf> {
os_imp::current_exe()
}
/// 进程参数的迭代器,为每个参数产生 [`String`] 值。
///
/// 该结构体由 [`env::args()`] 创建。有关更多信息,请参见其文档。
///
/// 第一个元素传统上是可执行文件的路径,但它可以设置为任意文本,甚至可能不存在。
/// 这意味着出于安全目的,不应依赖此属性。
///
/// [`env::args()`]: args
///
///
///
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "env", since = "1.0.0")]
pub struct Args {
inner: ArgsOs,
}
/// 一个进程参数的迭代器,为每个参数产生 [`OsString`] 值。
///
/// 该结构体由 [`env::args_os()`] 创建。有关更多信息,请参见其文档。
///
/// 第一个元素传统上是可执行文件的路径,但它可以设置为任意文本,甚至可能不存在。
/// 这意味着出于安全目的,不应依赖此属性。
///
/// [`env::args_os()`]: args_os
///
///
///
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "env", since = "1.0.0")]
pub struct ArgsOs {
inner: sys::args::Args,
}
/// 返回此程序开始的参数 (通常通过命令行传递)。
///
/// 第一个元素传统上是可执行文件的路径,但它可以设置为任意文本,甚至可能不存在。
///
/// 这意味着出于安全目的,不应依赖此属性。
///
/// 在 Unix 系统上,shell 通常使用 glob 模式 (例如 `*` 和 `?`) 来扩展不带引号的参数。
/// 在 Windows 上,这没有完成,并且此类参数按原样传递。
///
/// 在 glibc Linux 系统上,可以通过在 `.init_array` 中放置一个函数来检索参数。
/// glibc 将 `argc`、`argv` 和 `envp` 作为非标准扩展传递给 `.init_array` 中的函数。
/// 这使得 `std::env::args` 甚至可以在 `cdylib` 或 `staticlib` 上工作,就像在 macOS 和 Windows 上一样。
///
/// # Panics
///
/// 如果进程的任何参数不是有效的 Unicode,则返回的迭代器将在迭代期间 panic。
/// 如果不希望这样做,请改用 [`args_os`] 函数。
///
/// # Examples
///
/// ```
/// use std::env;
///
/// // 在单独的行上打印每个参数
/// for argument in env::args() {
/// println!("{argument}");
/// }
/// ```
///
///
///
///
#[stable(feature = "env", since = "1.0.0")]
pub fn args() -> Args {
Args { inner: args_os() }
}
/// 返回此程序开始的参数 (通常通过命令行传递)。
///
/// 第一个元素传统上是可执行文件的路径,但它可以设置为任意文本,甚至可能不存在。
///
/// 这意味着出于安全目的,不应依赖此属性。
///
/// 在 Unix 系统上,shell 通常使用 glob 模式 (例如 `*` 和 `?`) 来扩展不带引号的参数。
/// 在 Windows 上,这没有完成,并且此类参数按原样传递。
///
/// 在 glibc Linux 系统上,可以通过在 `.init_array` 中放置一个函数来检索参数。
/// glibc 将 `argc`、`argv` 和 `envp` 作为非标准扩展传递给 `.init_array` 中的函数。
/// 这使得 `std::env::args_os` 甚至可以在 `cdylib` 或 `staticlib` 中工作,就像在 macOS 和 Windows 上一样。
///
/// 请注意,返回的迭代器不会检查进程的参数是否为有效的 Unicode。
/// 如果您想在无效的 UTF-8 上使用 panic,请改用 [`args`] 函数。
///
/// # Examples
///
/// ```
/// use std::env;
///
/// // 在单独的行上打印每个参数
/// for argument in env::args_os() {
/// println!("{argument:?}");
/// }
/// ```
///
///
///
///
#[stable(feature = "env", since = "1.0.0")]
pub fn args_os() -> ArgsOs {
ArgsOs { inner: sys::args::args() }
}
#[stable(feature = "env_unimpl_send_sync", since = "1.26.0")]
impl !Send for Args {}
#[stable(feature = "env_unimpl_send_sync", since = "1.26.0")]
impl !Sync for Args {}
#[stable(feature = "env", since = "1.0.0")]
impl Iterator for Args {
type Item = String;
fn next(&mut self) -> Option<String> {
self.inner.next().map(|s| s.into_string().unwrap())
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
#[stable(feature = "env", since = "1.0.0")]
impl ExactSizeIterator for Args {
fn len(&self) -> usize {
self.inner.len()
}
fn is_empty(&self) -> bool {
self.inner.is_empty()
}
}
#[stable(feature = "env_iterators", since = "1.12.0")]
impl DoubleEndedIterator for Args {
fn next_back(&mut self) -> Option<String> {
self.inner.next_back().map(|s| s.into_string().unwrap())
}
}
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for Args {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Args").field("inner", &self.inner.inner).finish()
}
}
#[stable(feature = "env_unimpl_send_sync", since = "1.26.0")]
impl !Send for ArgsOs {}
#[stable(feature = "env_unimpl_send_sync", since = "1.26.0")]
impl !Sync for ArgsOs {}
#[stable(feature = "env", since = "1.0.0")]
impl Iterator for ArgsOs {
type Item = OsString;
fn next(&mut self) -> Option<OsString> {
self.inner.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
#[stable(feature = "env", since = "1.0.0")]
impl ExactSizeIterator for ArgsOs {
fn len(&self) -> usize {
self.inner.len()
}
fn is_empty(&self) -> bool {
self.inner.is_empty()
}
}
#[stable(feature = "env_iterators", since = "1.12.0")]
impl DoubleEndedIterator for ArgsOs {
fn next_back(&mut self) -> Option<OsString> {
self.inner.next_back()
}
}
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for ArgsOs {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ArgsOs").field("inner", &self.inner).finish()
}
}
/// 与当前目标关联的常量
#[stable(feature = "env", since = "1.0.0")]
pub mod consts {
use crate::sys::env::os;
/// 一个字符串,描述当前正在使用的 CPU 的体系结构。
///
///
/// 一些可能的值:
///
/// - x86
/// - x86_64
/// - arm
/// - aarch64
/// - loongarch64
/// - m68k
/// - mips
/// - mips64
/// - powerpc
/// - powerpc64
/// - riscv64
/// - s390x
/// - sparc64
#[stable(feature = "env", since = "1.0.0")]
pub const ARCH: &str = env!("STD_ENV_ARCH");
/// 操作系统的家族。示例值为 `unix`。
///
/// 一些可能的值:
///
/// - unix
/// - windows
#[stable(feature = "env", since = "1.0.0")]
pub const FAMILY: &str = os::FAMILY;
/// 描述正在使用的特定操作系统的字符串。
/// 示例值为 `linux`。
///
/// 一些可能的值:
///
/// - linux
/// - macos
/// - ios
/// - freebsd
/// - dragonfly
/// - netbsd
/// - openbsd
/// - solaris
/// - android
/// - windows
#[stable(feature = "env", since = "1.0.0")]
pub const OS: &str = os::OS;
/// 指定用于此平台上的共享库的文件名前缀。
/// 示例值为 `lib`。
///
/// 一些可能的值:
///
/// - lib
/// - `""` (空字符串)
#[stable(feature = "env", since = "1.0.0")]
pub const DLL_PREFIX: &str = os::DLL_PREFIX;
/// 指定此平台上共享库使用的文件名后缀。
/// 示例值为 `.so`。
///
/// 一些可能的值:
///
/// - .so
/// - .dylib
/// - .dll
#[stable(feature = "env", since = "1.0.0")]
pub const DLL_SUFFIX: &str = os::DLL_SUFFIX;
/// 指定此平台上共享库所用的文件扩展名,该扩展名位于点后。
/// 示例值为 `so`。
///
/// 一些可能的值:
///
/// - so
/// - dylib
/// - dll
#[stable(feature = "env", since = "1.0.0")]
pub const DLL_EXTENSION: &str = os::DLL_EXTENSION;
/// 指定用于此平台上的可执行二进制文件的文件名后缀。
/// 示例值为 `.exe`。
///
/// 一些可能的值:
///
/// - .exe
/// - .nexe
/// - .pexe
/// - `""` (空字符串)
#[stable(feature = "env", since = "1.0.0")]
pub const EXE_SUFFIX: &str = os::EXE_SUFFIX;
/// 指定用于此平台上的可执行二进制文件的文件扩展名 (如果有)。
/// 示例值为 `exe`。
///
/// 一些可能的值:
///
/// - exe
/// - `""` (空字符串)
#[stable(feature = "env", since = "1.0.0")]
pub const EXE_EXTENSION: &str = os::EXE_EXTENSION;
}