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
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
//! 用于处理进程的模块。
//!
//! 该模块主要与产生和与子进程交互有关,但是它也提供了 [`abort`] 和 [`exit`] 来终止当前进程。
//!
//! # 产生一个进程
//!
//! [`Command`] 结构体用于配置和 spawn 进程:
//!
//! ```no_run
//! use std::process::Command;
//!
//! let output = Command::new("echo")
//!                      .arg("Hello world")
//!                      .output()
//!                      .expect("Failed to execute command");
//!
//! assert_eq!(b"Hello world\n", output.stdout.as_slice());
//! ```
//!
//! [`Command`] 上的几种方法 (例如 [`spawn`] 或 [`output`]) 可用于 spawn 进程。
//! 特别是,[`output`] 生成子进程并等待直到该进程终止,而 [`spawn`] 将返回代表生成的子进程的 [`Child`]。
//!
//!
//! # 处理 I/O
//!
//! 可以通过将 [`Stdio`] 传递给 [`Command`] 上的相应方法来配置子进程的 [`stdout`],[`stdin`] 和 [`stderr`]。
//! 生成后,可以从 [`Child`] 访问它们。
//! 例如,可以将一个命令的输出管道输送到另一命令,如下所示:
//!
//! ```no_run
//! use std::process::{Command, Stdio};
//!
//! // stdout 必须配置 `Stdio::piped` 才能使用
//! // `echo_child.stdout`
//! let echo_child = Command::new("echo")
//!     .arg("Oh no, a tpyo!")
//!     .stdout(Stdio::piped())
//!     .spawn()
//!     .expect("Failed to start echo process");
//!
//! // 请注意,`echo_child` 已移到此处,但我们不再需要 `echo_child`
//! //
//! let echo_out = echo_child.stdout.expect("Failed to open echo stdout");
//!
//! let mut sed_child = Command::new("sed")
//!     .arg("s/tpyo/typo/")
//!     .stdin(Stdio::from(echo_out))
//!     .stdout(Stdio::piped())
//!     .spawn()
//!     .expect("Failed to start sed process");
//!
//! let output = sed_child.wait_with_output().expect("Failed to wait on sed");
//! assert_eq!(b"Oh no, a typo!\n", output.stdout.as_slice());
//! ```
//!
//! 请注意,[`ChildStderr`] 和 [`ChildStdout`] 实现 [`Read`],而 [`ChildStdin`] 实现 [`Write`]:
//!
//! ```no_run
//! use std::process::{Command, Stdio};
//! use std::io::Write;
//!
//! let mut child = Command::new("/bin/cat")
//!     .stdin(Stdio::piped())
//!     .stdout(Stdio::piped())
//!     .spawn()
//!     .expect("failed to execute child");
//!
//! // 如果子进程填充了其 stdout 缓冲区,则它可能最终会等待,直到父进程读取 stdout,并且在此期间无法读取 stdin,从而导致死锁。
//! //
//! // 从另一个线程进行写入可确保同时读取 stdout,从而避免了该问题。
//! //
//! //
//! let mut stdin = child.stdin.take().expect("failed to get stdin");
//! std::thread::spawn(move || {
//!     stdin.write_all(b"test").expect("failed to write to stdin");
//! });
//!
//! let output = child
//!     .wait_with_output()
//!     .expect("failed to wait on child");
//!
//! assert_eq!(b"test", output.stdout.as_slice());
//! ```
//!
//! [`spawn`]: Command::spawn
//! [`output`]: Command::output
//!
//! [`stdout`]: Command::stdout
//! [`stdin`]: Command::stdin
//! [`stderr`]: Command::stderr
//!
//! [`Write`]: io::Write
//! [`Read`]: io::Read
//!
//!
//!
//!
//!
//!

#![stable(feature = "process", since = "1.0.0")]
#![deny(unsafe_op_in_unsafe_fn)]

#[cfg(all(test, not(any(target_os = "emscripten", target_env = "sgx"))))]
mod tests;

use crate::io::prelude::*;

use crate::ffi::OsStr;
use crate::fmt;
use crate::fs;
use crate::io::{self, Initializer, IoSlice, IoSliceMut};
use crate::num::NonZeroI32;
use crate::path::Path;
use crate::str;
use crate::sys::pipe::{read2, AnonPipe};
use crate::sys::process as imp;
#[unstable(feature = "command_access", issue = "44434")]
pub use crate::sys_common::process::CommandEnvs;
use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};

/// 表示正在运行或退出的子进程。
///
/// 该结构体用于表示和管理子进程。
/// 子进程是通过 [`Command`] 结构体创建的,该子进程配置了生成进程,并且可以使用生成器样式的接口本身来创建子进程。
///
/// 子进程没有 [`Drop`] 的实现,所以如果您不确保 `Child` 已经退出,那么它会继续运行,即使在子进程的 `Child` 句柄已经离开作用域之后。
///
///
/// 调用 [`wait`] (或其他环绕它的函数) 将使父进程等待直到子进程实际退出后再继续。
///
/// # Warning
///
/// 在某些系统上,操作系统释放资源必须调用 [`wait`] 或类似方法。终止但尚未等待的进程仍然是 "zombie"。
/// 留下太多的僵尸可能会耗尽整个资源 (例如,进程 ID)。
///
/// 标准库不会自动等待子进程 (即使 `Child` 被丢弃也不会),这取决于应用程序开发人员。
/// 因此,在长时间运行的应用程序中,不建议先丢弃 `Child` 句柄而不先等待它们。
///
/// # Examples
///
/// ```should_panic
/// use std::process::Command;
///
/// let mut child = Command::new("/bin/cat")
///                         .arg("file.txt")
///                         .spawn()
///                         .expect("failed to execute child");
///
/// let ecode = child.wait()
///                  .expect("failed to wait on child");
///
/// assert!(ecode.success());
/// ```
///
/// [`wait`]: Child::wait
///
///
///
///
///
///
///
///
///
///
#[stable(feature = "process", since = "1.0.0")]
pub struct Child {
    handle: imp::Process,

    /// 写入子节点标准输入 (stdin) 的句柄 (如果已捕获)。
    /// 为避免部分移动 `child` 并因此阻止您自己在使用 `stdin` 时在 `child` 上调用函数,您可能会发现它很有用:
    ///
    ///
    /// ```compile_fail,E0425
    /// let stdin = child.stdin.take().unwrap();
    /// ```
    ///
    ///
    #[stable(feature = "process", since = "1.0.0")]
    pub stdin: Option<ChildStdin>,

    /// 从子节点的标准输出 (stdout) 读取的句柄 (如果已捕获)。
    /// 您可能会发现这样做很有帮助
    ///
    /// ```compile_fail,E0425
    /// let stdout = child.stdout.take().unwrap();
    /// ```
    ///
    /// 为了避免部分移动 `child`,从而在使用 `stdout` 时阻止自己在 `child` 上调用函数。
    ///
    #[stable(feature = "process", since = "1.0.0")]
    pub stdout: Option<ChildStdout>,

    /// 从子节点的标准错误 (stderr) 读取的句柄 (如果已捕获)。
    /// 您可能会发现这样做很有帮助
    ///
    /// ```compile_fail,E0425
    /// let stderr = child.stderr.take().unwrap();
    /// ```
    ///
    /// 为了避免部分移动 `child`,从而在使用 `stderr` 时阻止自己在 `child` 上调用函数。
    ///
    #[stable(feature = "process", since = "1.0.0")]
    pub stderr: Option<ChildStderr>,
}

impl AsInner<imp::Process> for Child {
    fn as_inner(&self) -> &imp::Process {
        &self.handle
    }
}

impl FromInner<(imp::Process, imp::StdioPipes)> for Child {
    fn from_inner((handle, io): (imp::Process, imp::StdioPipes)) -> Child {
        Child {
            handle,
            stdin: io.stdin.map(ChildStdin::from_inner),
            stdout: io.stdout.map(ChildStdout::from_inner),
            stderr: io.stderr.map(ChildStderr::from_inner),
        }
    }
}

impl IntoInner<imp::Process> for Child {
    fn into_inner(self) -> imp::Process {
        self.handle
    }
}

#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for Child {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Child")
            .field("stdin", &self.stdin)
            .field("stdout", &self.stdout)
            .field("stderr", &self.stderr)
            .finish_non_exhaustive()
    }
}

/// 子进程的标准输入 (stdin) 的句柄。
///
/// 该结构体用于 [`Child`] 的 [`stdin`] 字段中。
///
/// 当 `ChildStdin` 的实例是 [dropped] 时,`ChildStdin` 的基础文件句柄将关闭。
/// 如果子进程在丢弃之前已在输入上被阻止,则子进程将在丢弃后变为未阻止状态。
///
///
/// [`stdin`]: Child::stdin
/// [dropped]: Drop
#[stable(feature = "process", since = "1.0.0")]
pub struct ChildStdin {
    inner: AnonPipe,
}

#[stable(feature = "process", since = "1.0.0")]
impl Write for ChildStdin {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        (&*self).write(buf)
    }

    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
        (&*self).write_vectored(bufs)
    }

    fn is_write_vectored(&self) -> bool {
        io::Write::is_write_vectored(&&*self)
    }

    fn flush(&mut self) -> io::Result<()> {
        (&*self).flush()
    }
}

#[stable(feature = "write_mt", since = "1.48.0")]
impl Write for &ChildStdin {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.inner.write(buf)
    }

    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
        self.inner.write_vectored(bufs)
    }

    fn is_write_vectored(&self) -> bool {
        self.inner.is_write_vectored()
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

impl AsInner<AnonPipe> for ChildStdin {
    fn as_inner(&self) -> &AnonPipe {
        &self.inner
    }
}

impl IntoInner<AnonPipe> for ChildStdin {
    fn into_inner(self) -> AnonPipe {
        self.inner
    }
}

impl FromInner<AnonPipe> for ChildStdin {
    fn from_inner(pipe: AnonPipe) -> ChildStdin {
        ChildStdin { inner: pipe }
    }
}

#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for ChildStdin {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("ChildStdin").finish_non_exhaustive()
    }
}

/// 子进程的标准输出 (stdout) 的句柄。
///
/// 该结构体用于 [`Child`] 的 [`stdout`] 字段中。
///
/// 当 `ChildStdout` 的实例是 [dropped] 时,`ChildStdout` 的基础文件句柄将关闭。
///
///
/// [`stdout`]: Child::stdout
/// [dropped]: Drop
#[stable(feature = "process", since = "1.0.0")]
pub struct ChildStdout {
    inner: AnonPipe,
}

#[stable(feature = "process", since = "1.0.0")]
impl Read for ChildStdout {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.inner.read(buf)
    }

    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
        self.inner.read_vectored(bufs)
    }

    #[inline]
    fn is_read_vectored(&self) -> bool {
        self.inner.is_read_vectored()
    }

    #[inline]
    unsafe fn initializer(&self) -> Initializer {
        // SAFETY: 保证读取可以在未初始化的内存上进行
        unsafe { Initializer::nop() }
    }
}

impl AsInner<AnonPipe> for ChildStdout {
    fn as_inner(&self) -> &AnonPipe {
        &self.inner
    }
}

impl IntoInner<AnonPipe> for ChildStdout {
    fn into_inner(self) -> AnonPipe {
        self.inner
    }
}

impl FromInner<AnonPipe> for ChildStdout {
    fn from_inner(pipe: AnonPipe) -> ChildStdout {
        ChildStdout { inner: pipe }
    }
}

#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for ChildStdout {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("ChildStdout").finish_non_exhaustive()
    }
}

/// 子进程的 stderr 的句柄。
///
/// 该结构体用于 [`Child`] 的 [`stderr`] 字段中。
///
/// 当 `ChildStderr` 的实例是 [dropped] 时,`ChildStderr` 的基础文件句柄将关闭。
///
///
/// [`stderr`]: Child::stderr
/// [dropped]: Drop
#[stable(feature = "process", since = "1.0.0")]
pub struct ChildStderr {
    inner: AnonPipe,
}

#[stable(feature = "process", since = "1.0.0")]
impl Read for ChildStderr {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.inner.read(buf)
    }

    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
        self.inner.read_vectored(bufs)
    }

    #[inline]
    fn is_read_vectored(&self) -> bool {
        self.inner.is_read_vectored()
    }

    #[inline]
    unsafe fn initializer(&self) -> Initializer {
        // SAFETY: 保证读取可以在未初始化的内存上进行
        unsafe { Initializer::nop() }
    }
}

impl AsInner<AnonPipe> for ChildStderr {
    fn as_inner(&self) -> &AnonPipe {
        &self.inner
    }
}

impl IntoInner<AnonPipe> for ChildStderr {
    fn into_inner(self) -> AnonPipe {
        self.inner
    }
}

impl FromInner<AnonPipe> for ChildStderr {
    fn from_inner(pipe: AnonPipe) -> ChildStderr {
        ChildStderr { inner: pipe }
    }
}

#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for ChildStderr {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("ChildStderr").finish_non_exhaustive()
    }
}

/// 进程生成器,提供对如何生成新进程的细粒度控制。
///
/// 可以使用 `Command::new(program)` 生成默认配置,其中 `program` 提供了要执行的程序的路径。
///
/// 其他生成器方法允许在生成之前更改配置 (例如,通过添加参数) :
///
/// ```
/// use std::process::Command;
///
/// let output = if cfg!(target_os = "windows") {
///     Command::new("cmd")
///             .args(["/C", "echo hello"])
///             .output()
///             .expect("failed to execute process")
/// } else {
///     Command::new("sh")
///             .arg("-c")
///             .arg("echo hello")
///             .output()
///             .expect("failed to execute process")
/// };
///
/// let hello = output.stdout;
/// ```
///
/// `Command` 可以重用到 spawn 的多个进程。
/// 构建器方法无需立即使进程 spawn 即可更改命令。
///
/// ```no_run
/// use std::process::Command;
///
/// let mut echo_hello = Command::new("sh");
/// echo_hello.arg("-c")
///           .arg("echo hello");
/// let hello_1 = echo_hello.output().expect("failed to execute process");
/// let hello_2 = echo_hello.output().expect("failed to execute process");
/// ```
///
/// 同样,您可以在生成进程之后调用构建器方法,然后使用修改后的设置 spawn 新建一个进程。
///
/// ```no_run
/// use std::process::Command;
///
/// let mut list_dir = Command::new("ls");
///
/// // 在程序的当前目录中执行 `ls`。
/// list_dir.status().expect("process failed to execute");
///
/// println!();
///
/// // 更改 `ls` 以在根目录中执行。
/// list_dir.current_dir("/");
///
/// // 然后再次在根目录中执行 `ls`。
/// list_dir.status().expect("process failed to execute");
/// ```
///
///
///
#[stable(feature = "process", since = "1.0.0")]
pub struct Command {
    inner: imp::Command,
}

/// 允许在 `std` 内扩展 traits。
#[unstable(feature = "sealed", issue = "none")]
impl crate::sealed::Sealed for Command {}

impl Command {
    /// 使用以下默认配置创建一个新的 `Command`,以在路径 `program` 处启动该程序:
    ///
    /// * 程序无参数
    /// * 继承当前进程的环境
    /// * 继承当前进程的工作目录
    /// * 为 `spawn` 或 `status` 继承 stdin/stdout/stderr,但为 `output` 创建管道
    ///
    /// 提供了生成器方法来更改这些默认值,并以其他方式配置该进程。
    ///
    /// 如果 `program` 不是绝对路径,则将以 OS 定义的方式搜索 `PATH`。
    ///
    /// 可以通过在 Command 上设置 `PATH` 环境变量来控制要使用的搜索路径,但这在 Windows 上有一些实现上的限制 (请参见 issue #37519)。
    ///
    ///
    /// # Examples
    ///
    /// 基本用法:
    ///
    /// ```no_run
    /// use std::process::Command;
    ///
    /// Command::new("sh")
    ///         .spawn()
    ///         .expect("sh command failed to start");
    /// ```
    ///
    ///
    ///
    ///
    ///
    #[stable(feature = "process", since = "1.0.0")]
    pub fn new<S: AsRef<OsStr>>(program: S) -> Command {
        Command { inner: imp::Command::new(program.as_ref()) }
    }

    /// 添加参数以传递给程序。
    ///
    /// 每次使用只能传递一个参数。因此,而不是:
    ///
    /// ```no_run
    /// # std::process::Command::new("sh")
    /// .arg("-C /path/to/repo")
    /// # ;
    /// ```
    ///
    /// 用法是:
    ///
    /// ```no_run
    /// # std::process::Command::new("sh")
    /// .arg("-C")
    /// .arg("/path/to/repo")
    /// # ;
    /// ```
    ///
    /// 要传递多个参数,请参见 [`args`]。
    ///
    /// [`args`]: Command::args
    ///
    /// 注意,该参数不是通过 shell 传递的,而是按字面意义提供给程序的。
    /// 这意味着 shell 语法,例如引号,转义字符,单词拆分,全局模式,替换等。
    ///
    /// 没有效果。
    ///
    /// # Examples
    ///
    /// 基本用法:
    ///
    /// ```no_run
    /// use std::process::Command;
    ///
    /// Command::new("ls")
    ///         .arg("-l")
    ///         .arg("-a")
    ///         .spawn()
    ///         .expect("ls command failed to start");
    /// ```
    #[stable(feature = "process", since = "1.0.0")]
    pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Command {
        self.inner.arg(arg.as_ref());
        self
    }

    /// 添加多个参数以传递给程序。
    ///
    /// 要传递单个参数,请参见 [`arg`]。
    ///
    /// [`arg`]: Command::arg
    ///
    /// 请注意,该参数不是通过 shell 传递的,而是按字面意义提供给程序的。
    /// 这意味着 shell 语法,例如引号,转义字符,单词拆分,全局模式,替换等。
    ///
    /// 没有效果。
    ///
    /// # Examples
    ///
    /// 基本用法:
    ///
    /// ```no_run
    /// use std::process::Command;
    ///
    /// Command::new("ls")
    ///         .args(["-l", "-a"])
    ///         .spawn()
    ///         .expect("ls command failed to start");
    /// ```
    #[stable(feature = "process", since = "1.0.0")]
    pub fn args<I, S>(&mut self, args: I) -> &mut Command
    where
        I: IntoIterator<Item = S>,
        S: AsRef<OsStr>,
    {
        for arg in args {
            self.arg(arg.as_ref());
        }
        self
    }

    /// 插入或更新环境变量映射。
    ///
    /// 请注意,环境变量名称在 Windows 上不区分大小写 (但保留大小写),在所有其他平台上则区分大小写。
    ///
    ///
    /// # Examples
    ///
    /// 基本用法:
    ///
    /// ```no_run
    /// use std::process::Command;
    ///
    /// Command::new("ls")
    ///         .env("PATH", "/bin")
    ///         .spawn()
    ///         .expect("ls command failed to start");
    /// ```
    #[stable(feature = "process", since = "1.0.0")]
    pub fn env<K, V>(&mut self, key: K, val: V) -> &mut Command
    where
        K: AsRef<OsStr>,
        V: AsRef<OsStr>,
    {
        self.inner.env_mut().set(key.as_ref(), val.as_ref());
        self
    }

    /// 添加或更新多个环境变量映射。
    ///
    /// # Examples
    ///
    /// 基本用法:
    ///
    /// ```no_run
    /// use std::process::{Command, Stdio};
    /// use std::env;
    /// use std::collections::HashMap;
    ///
    /// let filtered_env : HashMap<String, String> =
    ///     env::vars().filter(|&(ref k, _)|
    ///         k == "TERM" || k == "TZ" || k == "LANG" || k == "PATH"
    ///     ).collect();
    ///
    /// Command::new("printenv")
    ///         .stdin(Stdio::null())
    ///         .stdout(Stdio::inherit())
    ///         .env_clear()
    ///         .envs(&filtered_env)
    ///         .spawn()
    ///         .expect("printenv failed to start");
    /// ```
    #[stable(feature = "command_envs", since = "1.19.0")]
    pub fn envs<I, K, V>(&mut self, vars: I) -> &mut Command
    where
        I: IntoIterator<Item = (K, V)>,
        K: AsRef<OsStr>,
        V: AsRef<OsStr>,
    {
        for (ref key, ref val) in vars {
            self.inner.env_mut().set(key.as_ref(), val.as_ref());
        }
        self
    }

    /// 删除环境变量映射。
    ///
    /// # Examples
    ///
    /// 基本用法:
    ///
    /// ```no_run
    /// use std::process::Command;
    ///
    /// Command::new("ls")
    ///         .env_remove("PATH")
    ///         .spawn()
    ///         .expect("ls command failed to start");
    /// ```
    #[stable(feature = "process", since = "1.0.0")]
    pub fn env_remove<K: AsRef<OsStr>>(&mut self, key: K) -> &mut Command {
        self.inner.env_mut().remove(key.as_ref());
        self
    }

    /// 清除子进程的整个环境 map。
    ///
    /// # Examples
    ///
    /// 基本用法:
    ///
    /// ```no_run
    /// use std::process::Command;
    ///
    /// Command::new("ls")
    ///         .env_clear()
    ///         .spawn()
    ///         .expect("ls command failed to start");
    /// ```
    #[stable(feature = "process", since = "1.0.0")]
    pub fn env_clear(&mut self) -> &mut Command {
        self.inner.env_mut().clear();
        self
    }

    /// 设置子进程的工作目录。
    ///
    /// # 平台特定的行为
    ///
    /// 如果程序路径是相对路径 (例如 `"./script.sh"`),则是相对于父级工作目录还是相对于 `current_dir` 来解释路径。
    /// 这种情况下的行为是特定于平台且不稳定的,建议使用 [`canonicalize`] 来获取绝对程序路径。
    ///
    /// # Examples
    ///
    /// 基本用法:
    ///
    /// ```no_run
    /// use std::process::Command;
    ///
    /// Command::new("ls")
    ///         .current_dir("/bin")
    ///         .spawn()
    ///         .expect("ls command failed to start");
    /// ```
    ///
    /// [`canonicalize`]: crate::fs::canonicalize
    ///
    ///
    ///
    #[stable(feature = "process", since = "1.0.0")]
    pub fn current_dir<P: AsRef<Path>>(&mut self, dir: P) -> &mut Command {
        self.inner.cwd(dir.as_ref().as_ref());
        self
    }

    /// 子进程的标准输入 (stdin) 句柄的配置。
    ///
    /// 与 `spawn` 或 `status` 一起使用时默认为 [`inherit`],与 `output` 一起使用时默认为 [`piped`]。
    ///
    ///
    /// [`inherit`]: Stdio::inherit
    /// [`piped`]: Stdio::piped
    ///
    /// # Examples
    ///
    /// 基本用法:
    ///
    /// ```no_run
    /// use std::process::{Command, Stdio};
    ///
    /// Command::new("ls")
    ///         .stdin(Stdio::null())
    ///         .spawn()
    ///         .expect("ls command failed to start");
    /// ```
    #[stable(feature = "process", since = "1.0.0")]
    pub fn stdin<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {
        self.inner.stdin(cfg.into().0);
        self
    }

    /// 子进程的标准输出 (stdout) 句柄的配置。
    ///
    /// 与 `spawn` 或 `status` 一起使用时默认为 [`inherit`],与 `output` 一起使用时默认为 [`piped`]。
    ///
    ///
    /// [`inherit`]: Stdio::inherit
    /// [`piped`]: Stdio::piped
    ///
    /// # Examples
    ///
    /// 基本用法:
    ///
    /// ```no_run
    /// use std::process::{Command, Stdio};
    ///
    /// Command::new("ls")
    ///         .stdout(Stdio::null())
    ///         .spawn()
    ///         .expect("ls command failed to start");
    /// ```
    #[stable(feature = "process", since = "1.0.0")]
    pub fn stdout<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {
        self.inner.stdout(cfg.into().0);
        self
    }

    /// 子进程的标准错误 (stderr) 句柄的配置。
    ///
    /// 与 `spawn` 或 `status` 一起使用时默认为 [`inherit`],与 `output` 一起使用时默认为 [`piped`]。
    ///
    ///
    /// [`inherit`]: Stdio::inherit
    /// [`piped`]: Stdio::piped
    ///
    /// # Examples
    ///
    /// 基本用法:
    ///
    /// ```no_run
    /// use std::process::{Command, Stdio};
    ///
    /// Command::new("ls")
    ///         .stderr(Stdio::null())
    ///         .spawn()
    ///         .expect("ls command failed to start");
    /// ```
    #[stable(feature = "process", since = "1.0.0")]
    pub fn stderr<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {
        self.inner.stderr(cfg.into().0);
        self
    }

    /// 将命令作为子进程执行,并返回其句柄。
    ///
    /// 默认情况下,stdin、stdout 和 stderr 都是从父级继承的。
    ///
    /// # Examples
    ///
    /// 基本用法:
    ///
    /// ```no_run
    /// use std::process::Command;
    ///
    /// Command::new("ls")
    ///         .spawn()
    ///         .expect("ls command failed to start");
    /// ```
    #[stable(feature = "process", since = "1.0.0")]
    pub fn spawn(&mut self) -> io::Result<Child> {
        self.inner.spawn(imp::Stdio::Inherit, true).map(Child::from_inner)
    }

    /// 将命令作为子进程执行,等待其完成并收集所有输出。
    ///
    /// 默认情况下,将捕获 stdout 和 stderr (并用于提供结果输出)。
    /// Stdin 不是从父级继承的,子进程尝试从 stdin 流中进行读取的任何尝试都将导致该流立即关闭。
    ///
    ///
    /// # Examples
    ///
    /// ```should_panic
    /// use std::process::Command;
    /// use std::io::{self, Write};
    /// let output = Command::new("/bin/cat")
    ///                      .arg("file.txt")
    ///                      .output()
    ///                      .expect("failed to execute process");
    ///
    /// println!("status: {}", output.status);
    /// io::stdout().write_all(&output.stdout).unwrap();
    /// io::stderr().write_all(&output.stderr).unwrap();
    ///
    /// assert!(output.status.success());
    /// ```
    ///
    ///
    #[stable(feature = "process", since = "1.0.0")]
    pub fn output(&mut self) -> io::Result<Output> {
        self.inner
            .spawn(imp::Stdio::MakePipe, false)
            .map(Child::from_inner)
            .and_then(|p| p.wait_with_output())
    }

    /// 将命令作为子进程执行,等待其完成并收集其状态。
    ///
    ///
    /// 默认情况下,stdin、stdout 和 stderr 都是从父级继承的。
    ///
    /// # Examples
    ///
    /// ```should_panic
    /// use std::process::Command;
    ///
    /// let status = Command::new("/bin/cat")
    ///                      .arg("file.txt")
    ///                      .status()
    ///                      .expect("failed to execute process");
    ///
    /// println!("process finished with: {}", status);
    ///
    /// assert!(status.success());
    /// ```
    #[stable(feature = "process", since = "1.0.0")]
    pub fn status(&mut self) -> io::Result<ExitStatus> {
        self.inner
            .spawn(imp::Stdio::Inherit, true)
            .map(Child::from_inner)
            .and_then(|mut p| p.wait())
    }

    /// 返回给 [`Command::new`] 的程序的路径。
    ///
    /// # Examples
    ///
    /// ```
    /// # #![feature(command_access)]
    /// use std::process::Command;
    ///
    /// let cmd = Command::new("echo");
    /// assert_eq!(cmd.get_program(), "echo");
    /// ```
    #[unstable(feature = "command_access", issue = "44434")]
    pub fn get_program(&self) -> &OsStr {
        self.inner.get_program()
    }

    /// 返回将传递给程序的参数的迭代器。
    ///
    /// 这不包括程序的路径作为第一个参数;
    /// 它仅包含 [`Command::arg`] 和 [`Command::args`] 指定的参数。
    ///
    ///
    /// # Examples
    ///
    /// ```
    /// # #![feature(command_access)]
    /// use std::ffi::OsStr;
    /// use std::process::Command;
    ///
    /// let mut cmd = Command::new("echo");
    /// cmd.arg("first").arg("second");
    /// let args: Vec<&OsStr> = cmd.get_args().collect();
    /// assert_eq!(args, &["first", "second"]);
    /// ```
    #[unstable(feature = "command_access", issue = "44434")]
    pub fn get_args(&self) -> CommandArgs<'_> {
        CommandArgs { inner: self.inner.get_args() }
    }

    /// 返回将在生成进程时设置的环境变量的迭代器。
    ///
    /// 每个元素都是一个元组 `(&OsStr, Option<&OsStr>)`,其中第一个值为键,第二个为值,如果要显式删除环境变量,则为 [`None`]。
    ///
    ///
    /// 这仅包括用 [`Command::env`],[`Command::envs`] 和 [`Command::env_remove`] 显式设置的环境变量。
    /// 它不包括子进程将继承的环境变量。
    ///
    /// # Examples
    ///
    /// ```
    /// # #![feature(command_access)]
    /// use std::ffi::OsStr;
    /// use std::process::Command;
    ///
    /// let mut cmd = Command::new("ls");
    /// cmd.env("TERM", "dumb").env_remove("TZ");
    /// let envs: Vec<(&OsStr, Option<&OsStr>)> = cmd.get_envs().collect();
    /// assert_eq!(envs, &[
    ///     (OsStr::new("TERM"), Some(OsStr::new("dumb"))),
    ///     (OsStr::new("TZ"), None)
    /// ]);
    /// ```
    ///
    ///
    ///
    ///
    #[unstable(feature = "command_access", issue = "44434")]
    pub fn get_envs(&self) -> CommandEnvs<'_> {
        self.inner.get_envs()
    }

    /// 返回子进程的工作目录。
    ///
    /// 如果不更改工作目录,则返回 [`None`]。
    ///
    /// # Examples
    ///
    /// ```
    /// # #![feature(command_access)]
    /// use std::path::Path;
    /// use std::process::Command;
    ///
    /// let mut cmd = Command::new("ls");
    /// assert_eq!(cmd.get_current_dir(), None);
    /// cmd.current_dir("/bin");
    /// assert_eq!(cmd.get_current_dir(), Some(Path::new("/bin")));
    /// ```
    #[unstable(feature = "command_access", issue = "44434")]
    pub fn get_current_dir(&self) -> Option<&Path> {
        self.inner.get_current_dir()
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Debug for Command {
    /// 格式化命令的程序和参数以进行显示。
    /// 使用 utf8 替换字符有损地转换所有非 utf8 数据。
    ///
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.inner.fmt(f)
    }
}

impl AsInner<imp::Command> for Command {
    fn as_inner(&self) -> &imp::Command {
        &self.inner
    }
}

impl AsInnerMut<imp::Command> for Command {
    fn as_inner_mut(&mut self) -> &mut imp::Command {
        &mut self.inner
    }
}

/// 命令的迭代器。
///
/// 该结构体由 [`Command::get_args`] 创建。
/// 有关更多信息,请参见其文档。
#[unstable(feature = "command_access", issue = "44434")]
#[derive(Debug)]
pub struct CommandArgs<'a> {
    inner: imp::CommandArgs<'a>,
}

#[unstable(feature = "command_access", issue = "44434")]
impl<'a> Iterator for CommandArgs<'a> {
    type Item = &'a OsStr;
    fn next(&mut self) -> Option<&'a OsStr> {
        self.inner.next()
    }
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.inner.size_hint()
    }
}

#[unstable(feature = "command_access", issue = "44434")]
impl<'a> ExactSizeIterator for CommandArgs<'a> {
    fn len(&self) -> usize {
        self.inner.len()
    }
    fn is_empty(&self) -> bool {
        self.inner.is_empty()
    }
}

/// 完成的进程的输出。
///
/// [`Command`] 的 [`output`] 方法或 [`Child`] 进程的 [`wait_with_output`] 方法在结果中返回该值。
///
///
/// [`output`]: Command::output
/// [`wait_with_output`]: Child::wait_with_output
///
#[derive(PartialEq, Eq, Clone)]
#[stable(feature = "process", since = "1.0.0")]
pub struct Output {
    /// 进程的状态 (退出代码)。
    #[stable(feature = "process", since = "1.0.0")]
    pub status: ExitStatus,
    /// 进程写入 stdout 的数据。
    #[stable(feature = "process", since = "1.0.0")]
    pub stdout: Vec<u8>,
    /// 进程写入 stderr 的数据。
    #[stable(feature = "process", since = "1.0.0")]
    pub stderr: Vec<u8>,
}

// 如果 stderr 或 stdout 是有效的 utf8 字符串,它将打印有效的字符串,否则将打印字节序列。
//
#[stable(feature = "process_output_debug", since = "1.7.0")]
impl fmt::Debug for Output {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        let stdout_utf8 = str::from_utf8(&self.stdout);
        let stdout_debug: &dyn fmt::Debug = match stdout_utf8 {
            Ok(ref str) => str,
            Err(_) => &self.stdout,
        };

        let stderr_utf8 = str::from_utf8(&self.stderr);
        let stderr_debug: &dyn fmt::Debug = match stderr_utf8 {
            Ok(ref str) => str,
            Err(_) => &self.stderr,
        };

        fmt.debug_struct("Output")
            .field("status", &self.status)
            .field("stdout", stdout_debug)
            .field("stderr", stderr_debug)
            .finish()
    }
}

/// 描述当传递给 [`Command`] 的 [`stdin`],[`stdout`] 和 [`stderr`] 方法时,如何对子进程使用标准 I/O 流。
///
///
/// [`stdin`]: Command::stdin
/// [`stdout`]: Command::stdout
/// [`stderr`]: Command::stderr
#[stable(feature = "process", since = "1.0.0")]
pub struct Stdio(imp::Stdio);

impl Stdio {
    /// 应该安排一个新管道来连接父进程和子进程。
    ///
    /// # Examples
    ///
    /// 使用 stdout:
    ///
    /// ```no_run
    /// use std::process::{Command, Stdio};
    ///
    /// let output = Command::new("echo")
    ///     .arg("Hello, world!")
    ///     .stdout(Stdio::piped())
    ///     .output()
    ///     .expect("Failed to execute command");
    ///
    /// assert_eq!(String::from_utf8_lossy(&output.stdout), "Hello, world!\n");
    /// // 控制台没有回显
    /// ```
    ///
    /// 使用 stdin:
    ///
    /// ```no_run
    /// use std::io::Write;
    /// use std::process::{Command, Stdio};
    ///
    /// let mut child = Command::new("rev")
    ///     .stdin(Stdio::piped())
    ///     .stdout(Stdio::piped())
    ///     .spawn()
    ///     .expect("Failed to spawn child process");
    ///
    /// let mut stdin = child.stdin.take().expect("Failed to open stdin");
    /// std::thread::spawn(move || {
    ///     stdin.write_all("Hello, world!".as_bytes()).expect("Failed to write to stdin");
    /// });
    ///
    /// let output = child.wait_with_output().expect("Failed to read stdout");
    /// assert_eq!(String::from_utf8_lossy(&output.stdout), "!dlrow ,olleH");
    /// ```
    ///
    /// 在不同时读取 stdout 和 stderr 的情况下,向 stdin 写入超过管道缓冲区的输入值可能会导致死锁。
    /// 这在运行任何不能保证在写入超过管道缓冲区的输出值之前不能保证读取其整个 stdin 的程序时就是一个问题。
    ///
    /// 管道缓冲区的大小在不同的目标上有所不同。
    ///
    ///
    #[stable(feature = "process", since = "1.0.0")]
    pub fn piped() -> Stdio {
        Stdio(imp::Stdio::MakePipe)
    }

    /// 子级从相应的父级描述符继承。
    ///
    /// # Examples
    ///
    /// 使用 stdout:
    ///
    /// ```no_run
    /// use std::process::{Command, Stdio};
    ///
    /// let output = Command::new("echo")
    ///     .arg("Hello, world!")
    ///     .stdout(Stdio::inherit())
    ///     .output()
    ///     .expect("Failed to execute command");
    ///
    /// assert_eq!(String::from_utf8_lossy(&output.stdout), "");
    /// // "Hello, world!" 回显到控制台
    /// ```
    ///
    /// 使用 stdin:
    ///
    /// ```no_run
    /// use std::process::{Command, Stdio};
    /// use std::io::{self, Write};
    ///
    /// let output = Command::new("rev")
    ///     .stdin(Stdio::inherit())
    ///     .stdout(Stdio::piped())
    ///     .output()
    ///     .expect("Failed to execute command");
    ///
    /// print!("You piped in the reverse of: ");
    /// io::stdout().write_all(&output.stdout).unwrap();
    /// ```
    #[stable(feature = "process", since = "1.0.0")]
    pub fn inherit() -> Stdio {
        Stdio(imp::Stdio::Inherit)
    }

    /// 此流将被忽略。
    /// 这等效于将流附加到 `/dev/null`。
    ///
    /// # Examples
    ///
    /// 使用 stdout:
    ///
    /// ```no_run
    /// use std::process::{Command, Stdio};
    ///
    /// let output = Command::new("echo")
    ///     .arg("Hello, world!")
    ///     .stdout(Stdio::null())
    ///     .output()
    ///     .expect("Failed to execute command");
    ///
    /// assert_eq!(String::from_utf8_lossy(&output.stdout), "");
    /// // 控制台没有回显
    /// ```
    ///
    /// 使用 stdin:
    ///
    /// ```no_run
    /// use std::process::{Command, Stdio};
    ///
    /// let output = Command::new("rev")
    ///     .stdin(Stdio::null())
    ///     .stdout(Stdio::piped())
    ///     .output()
    ///     .expect("Failed to execute command");
    ///
    /// assert_eq!(String::from_utf8_lossy(&output.stdout), "");
    /// // 忽略任何管道输入
    /// ```
    #[stable(feature = "process", since = "1.0.0")]
    pub fn null() -> Stdio {
        Stdio(imp::Stdio::Null)
    }
}

impl FromInner<imp::Stdio> for Stdio {
    fn from_inner(inner: imp::Stdio) -> Stdio {
        Stdio(inner)
    }
}

#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for Stdio {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Stdio").finish_non_exhaustive()
    }
}

#[stable(feature = "stdio_from", since = "1.20.0")]
impl From<ChildStdin> for Stdio {
    /// 将 `ChildStdin` 转换为 `Stdio`
    ///
    /// # Examples
    ///
    /// `ChildStdin` 将在引擎盖下使用 `Stdio::from` 转换为 `Stdio`。
    ///
    /// ```rust,no_run
    /// use std::process::{Command, Stdio};
    ///
    /// let reverse = Command::new("rev")
    ///     .stdin(Stdio::piped())
    ///     .spawn()
    ///     .expect("failed reverse command");
    ///
    /// let _echo = Command::new("echo")
    ///     .arg("Hello, world!")
    ///     .stdout(reverse.stdin.unwrap()) // 在此处转换为 Stdio
    ///     .output()
    ///     .expect("failed echo command");
    ///
    /// // "!dlrow ,olleH" 回显到控制台
    /// ```
    fn from(child: ChildStdin) -> Stdio {
        Stdio::from_inner(child.into_inner().into())
    }
}

#[stable(feature = "stdio_from", since = "1.20.0")]
impl From<ChildStdout> for Stdio {
    /// 将 `ChildStdout` 转换为 `Stdio`
    ///
    /// # Examples
    ///
    /// `ChildStdout` 将在引擎盖下使用 `Stdio::from` 转换为 `Stdio`。
    ///
    /// ```rust,no_run
    /// use std::process::{Command, Stdio};
    ///
    /// let hello = Command::new("echo")
    ///     .arg("Hello, world!")
    ///     .stdout(Stdio::piped())
    ///     .spawn()
    ///     .expect("failed echo command");
    ///
    /// let reverse = Command::new("rev")
    ///     .stdin(hello.stdout.unwrap())  // 在此处转换为 Stdio
    ///     .output()
    ///     .expect("failed reverse command");
    ///
    /// assert_eq!(reverse.stdout, b"!dlrow ,olleH\n");
    /// ```
    fn from(child: ChildStdout) -> Stdio {
        Stdio::from_inner(child.into_inner().into())
    }
}

#[stable(feature = "stdio_from", since = "1.20.0")]
impl From<ChildStderr> for Stdio {
    /// 将 `ChildStderr` 转换为 `Stdio`
    ///
    /// # Examples
    ///
    /// ```rust,no_run
    /// use std::process::{Command, Stdio};
    ///
    /// let reverse = Command::new("rev")
    ///     .arg("non_existing_file.txt")
    ///     .stderr(Stdio::piped())
    ///     .spawn()
    ///     .expect("failed reverse command");
    ///
    /// let cat = Command::new("cat")
    ///     .arg("-")
    ///     .stdin(reverse.stderr.unwrap()) // 在此处转换为 Stdio
    ///     .output()
    ///     .expect("failed echo command");
    ///
    /// assert_eq!(
    ///     String::from_utf8_lossy(&cat.stdout),
    ///     "rev: cannot open non_existing_file.txt: No such file or directory\n"
    /// );
    /// ```
    fn from(child: ChildStderr) -> Stdio {
        Stdio::from_inner(child.into_inner().into())
    }
}

#[stable(feature = "stdio_from", since = "1.20.0")]
impl From<fs::File> for Stdio {
    /// 将 `File` 转换为 `Stdio`
    ///
    /// # Examples
    ///
    /// `File` 将在引擎盖下使用 `Stdio::from` 转换为 `Stdio`。
    ///
    /// ```rust,no_run
    /// use std::fs::File;
    /// use std::process::Command;
    ///
    /// // 使用包含 `Hello,world! ` 的 `foo.txt` 文件。
    /// let file = File::open("foo.txt").unwrap();
    ///
    /// let reverse = Command::new("rev")
    ///     .stdin(file)  // 隐式文件转换为 Stdio
    ///     .output()
    ///     .expect("failed reverse command");
    ///
    /// assert_eq!(reverse.stdout, b"!dlrow ,olleH");
    /// ```
    fn from(file: fs::File) -> Stdio {
        Stdio::from_inner(file.into_inner().into())
    }
}

/// 描述进程终止后的结果。
///
/// `struct` 用于表示子进程的退出状态或其他终止。
/// 子进程是通过 [`Command`] 结构体创建的,其退出状态通过 [`status`] 方法或 [`Child`] 进程的 [`wait`] 方法公开。
///
///
/// `ExitStatus` 表示进程的每一种可能的配置。在 Unix 上,这是等待状态。
/// *不是* 仅仅是 *exit 状态*(传递给 `exit` 的值)。
///
/// 为了正确报告失败进程的错误,请使用 [`Display`](crate::fmt::Display) 的实现打印 `ExitStatus` 或 `ExitStatusError` 的值。
///
/// [`status`]: Command::status
/// [`wait`]: Child::wait
///
///
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
#[stable(feature = "process", since = "1.0.0")]
pub struct ExitStatus(imp::ExitStatus);

/// 允许在 `std` 内扩展 traits。
#[unstable(feature = "sealed", issue = "none")]
impl crate::sealed::Sealed for ExitStatus {}

impl ExitStatus {
    /// 终止成功了吗?  返回 `Result`。
    ///
    /// # Examples
    ///
    /// ```
    /// #![feature(exit_status_error)]
    /// # if cfg!(unix) {
    /// use std::process::Command;
    ///
    /// let status = Command::new("ls")
    ///                      .arg("/dev/nonexistent")
    ///                      .status()
    ///                      .expect("ls could not be executed");
    ///
    /// println!("ls: {}", status);
    /// status.exit_ok().expect_err("/dev/nonexistent could be listed!");
    /// # } // cfg!(unix)
    /// ```
    #[unstable(feature = "exit_status_error", issue = "84908")]
    pub fn exit_ok(&self) -> Result<(), ExitStatusError> {
        self.0.exit_ok().map_err(ExitStatusError)
    }

    /// 终止成功了吗? 信号终止不被视为成功,并且成功被定义为零退出状态。
    ///
    ///
    /// # Examples
    ///
    /// ```rust,no_run
    /// use std::process::Command;
    ///
    /// let status = Command::new("mkdir")
    ///                      .arg("projects")
    ///                      .status()
    ///                      .expect("failed to execute mkdir");
    ///
    /// if status.success() {
    ///     println!("'projects/' directory created");
    /// } else {
    ///     println!("failed to create 'projects/' directory: {}", status);
    /// }
    /// ```
    #[stable(feature = "process", since = "1.0.0")]
    pub fn success(&self) -> bool {
        self.0.exit_ok().is_ok()
    }

    /// 返回进程的退出代码 (如果有)。
    ///
    /// 用 Unix 的术语来说,返回值是退出状态: 如果进程通过调用 `exit` 完成,则传递给 `exit` 的值。
    /// 请注意,在 Unix 上,退出状态被截断为 8 位,并且不是从程序调用 `exit` 来的值可能是在运行时系统中发明的 (通常是 255、254、127 或 126)。
    ///
    ///
    /// 在 Unix 上,如果进程被信号终止,它将返回 `None`。
    /// [`ExitStatusExt`](crate::os::unix::process::ExitStatusExt) 是 trait 的扩展名,用于从 `ExitStatus` 中提取任何此类信号以及其他详细信息。
    ///
    /// # Examples
    ///
    /// ```no_run
    /// use std::process::Command;
    ///
    /// let status = Command::new("mkdir")
    ///                      .arg("projects")
    ///                      .status()
    ///                      .expect("failed to execute mkdir");
    ///
    /// match status.code() {
    ///     Some(code) => println!("Exited with status code: {}", code),
    ///     None       => println!("Process terminated by signal")
    /// }
    /// ```
    ///
    ///
    #[stable(feature = "process", since = "1.0.0")]
    pub fn code(&self) -> Option<i32> {
        self.0.code()
    }
}

impl AsInner<imp::ExitStatus> for ExitStatus {
    fn as_inner(&self) -> &imp::ExitStatus {
        &self.0
    }
}

impl FromInner<imp::ExitStatus> for ExitStatus {
    fn from_inner(s: imp::ExitStatus) -> ExitStatus {
        ExitStatus(s)
    }
}

#[stable(feature = "process", since = "1.0.0")]
impl fmt::Display for ExitStatus {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.0.fmt(f)
    }
}

/// 允许在 `std` 内扩展 traits。
#[unstable(feature = "sealed", issue = "none")]
impl crate::sealed::Sealed for ExitStatusError {}

/// 描述进程失败后的结果
///
/// 通过 [`ExitStatus`] 上的 [`.exit_ok`](ExitStatus::exit_ok) 方法生成。
///
/// # Examples
///
/// ```
/// #![feature(exit_status_error)]
/// # if cfg!(unix) {
/// use std::process::{Command, ExitStatusError};
///
/// fn run(cmd: &str) -> Result<(),ExitStatusError> {
///     Command::new(cmd).status().unwrap().exit_ok()?;
///     Ok(())
/// }
///
/// run("true").unwrap();
/// run("false").unwrap_err();
/// # } // cfg!(unix)
/// ```
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
#[unstable(feature = "exit_status_error", issue = "84908")]
// 理想情况下,imp::ExitStatusError 的定义应该是 Result<(), imp::ExitStatusError> 与 imp::ExitStatus 具有相同的表示。
//
pub struct ExitStatusError(imp::ExitStatusError);

#[unstable(feature = "exit_status_error", issue = "84908")]
impl ExitStatusError {
    /// 从 `ExitStatusError` 报告退出代码 (如果适用)。
    ///
    /// 用 Unix 的术语来说,返回值是退出状态: 如果进程通过调用 `exit` 完成,则传递给 `exit` 的值。
    /// 请注意,在 Unix 上,退出状态被截断为 8 位,并且不是来自程序调用到 `exit` 的值可能是由运行时系统发明的 (通常,例如,255、254、127 或 126)。
    ///
    ///
    /// 在 Unix 上,如果进程被信号终止,它将返回 `None`。
    /// 如果您想专门处理这种情况,请考虑使用 [`ExitStatusExt`](crate::os::unix::process::ExitStatusExt) 中的方法。
    ///
    /// 如果进程通过使用非零值调用 `exit` 完成,这将返回该退出状态。
    ///
    /// 如果错误是其他原因,它将返回 `None`。
    ///
    /// 如果进程成功退出 (即通过调用 `exit(0)`),则没有 `ExitStatusError`。所以 `ExitStatusError::code()` 的返回值总是非零。
    ///
    /// # Examples
    ///
    /// ```
    /// #![feature(exit_status_error)]
    /// # #[cfg(unix)] {
    /// use std::process::Command;
    ///
    /// let bad = Command::new("false").status().unwrap().exit_ok().unwrap_err();
    /// assert_eq!(bad.code(), Some(1));
    /// # } // #[cfg(unix)]
    /// ```
    ///
    ///
    ///
    ///
    pub fn code(&self) -> Option<i32> {
        self.code_nonzero().map(Into::into)
    }

    /// 将 `ExitStatusError` 的退出代码 (如果适用) 报告为 `NonZero`
    ///
    /// 这与 [`code()`](Self::code) 完全一样,只是它返回一个 `NonZeroI32`。
    ///
    /// 提供普通 `code`,返回一个普通整数,因为它通常更方便。
    /// `code()` 的返回值确实也是非零的; 当您想要非零的类型级别保证时,请使用 `code_nonzero()`。
    ///
    ///
    /// # Examples
    ///
    /// ```
    /// #![feature(exit_status_error)]
    /// # if cfg!(unix) {
    /// use std::convert::TryFrom;
    /// use std::num::NonZeroI32;
    /// use std::process::Command;
    ///
    /// let bad = Command::new("false").status().unwrap().exit_ok().unwrap_err();
    /// assert_eq!(bad.code_nonzero().unwrap(), NonZeroI32::try_from(1).unwrap());
    /// # } // cfg!(unix)
    /// ```
    pub fn code_nonzero(&self) -> Option<NonZeroI32> {
        self.0.code()
    }

    /// 将 `ExitStatusError` (back) 转换为 `ExitStatus`。
    pub fn into_status(&self) -> ExitStatus {
        ExitStatus(self.0.into())
    }
}

#[unstable(feature = "exit_status_error", issue = "84908")]
impl Into<ExitStatus> for ExitStatusError {
    fn into(self) -> ExitStatus {
        ExitStatus(self.0.into())
    }
}

#[unstable(feature = "exit_status_error", issue = "84908")]
impl fmt::Display for ExitStatusError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "process exited unsuccessfully: {}", self.into_status())
    }
}

#[unstable(feature = "exit_status_error", issue = "84908")]
impl crate::error::Error for ExitStatusError {}

/// 此类型表示进程在正常终止下可以返回其父级的状态代码。
///
/// 此类型中使用的数字值没有可移植的含义,并且不同的平台可能会掩盖不同数量的含义。
///
/// 有关平台的规范成功和失败代码,请参见 [`SUCCESS`] 和 [`FAILURE`] 关联项。
///
/// [`SUCCESS`]: ExitCode::SUCCESS
/// [`FAILURE`]: ExitCode::FAILURE
///
/// **警告**: 虽然在 [RFC #1937] 中讨论了各种形式,但最终还是从 RFC 中删除了该形式,因此,与通常的不稳定项搅动相比,该类型更容易发生变化。
///
///
/// [RFC #1937]: https://github.com/rust-lang/rfcs/pull/1937
///
///
///
///
#[derive(Clone, Copy, Debug)]
#[unstable(feature = "process_exitcode_placeholder", issue = "48711")]
pub struct ExitCode(imp::ExitCode);

#[unstable(feature = "process_exitcode_placeholder", issue = "48711")]
impl ExitCode {
    /// 在此平台上成功终止的规范 ExitCode。
    ///
    /// 请注意,返回 `main` 的 ` () ` 隐式导致成功终止,因此除非您还返回了其他可能的代码,否则无需从 `main` 返回此值。
    ///
    ///
    #[unstable(feature = "process_exitcode_placeholder", issue = "48711")]
    pub const SUCCESS: ExitCode = ExitCode(imp::ExitCode::SUCCESS);

    /// 在此平台上无法成功终止的规范 ExitCode。
    ///
    /// 如果仅从 `main` 返回此代码和 `SUCCESS`,则考虑分别返回 `Err(_)` 和 `Ok(())`,这将返回相同的代码 (但也会返回 `eprintln!` 错误)。
    ///
    ///
    #[unstable(feature = "process_exitcode_placeholder", issue = "48711")]
    pub const FAILURE: ExitCode = ExitCode(imp::ExitCode::FAILURE);
}

impl Child {
    /// 强制子进程退出。
    /// 如果子节点已经退出,则返回 [`InvalidInput`] 错误。
    ///
    /// 到 [`ErrorKind`] 的映射不是函数的兼容性契约的一部分。
    ///
    /// 这等效于在 Unix 平台上发送 SIGKILL。
    ///
    /// # Examples
    ///
    /// 基本用法:
    ///
    /// ```no_run
    /// use std::process::Command;
    ///
    /// let mut command = Command::new("yes");
    /// if let Ok(mut child) = command.spawn() {
    ///     child.kill().expect("command wasn't running");
    /// } else {
    ///     println!("yes command didn't start");
    /// }
    /// ```
    ///
    /// [`ErrorKind`]: io::ErrorKind
    /// [`InvalidInput`]: io::ErrorKind::InvalidInput
    #[stable(feature = "process", since = "1.0.0")]
    pub fn kill(&mut self) -> io::Result<()> {
        self.handle.kill()
    }

    /// 返回与此子级关联的操作系统分配的进程标识符。
    ///
    /// # Examples
    ///
    /// 基本用法:
    ///
    /// ```no_run
    /// use std::process::Command;
    ///
    /// let mut command = Command::new("ls");
    /// if let Ok(child) = command.spawn() {
    ///     println!("Child's ID is {}", child.id());
    /// } else {
    ///     println!("ls command didn't start");
    /// }
    /// ```
    #[stable(feature = "process_id", since = "1.3.0")]
    pub fn id(&self) -> u32 {
        self.handle.id()
    }

    /// 等待子节点完全退出,并返回退出时的状态。
    /// 至少调用一次之后,该函数将继续具有相同的返回值。
    ///
    /// 子进程的 stdin 句柄 (如果有) 将在等待之前关闭。
    /// 这有助于避免死锁: 它确保子进程在父进程等待子进程退出时不会阻止其等待父进程的输入。
    ///
    ///
    /// # Examples
    ///
    /// 基本用法:
    ///
    /// ```no_run
    /// use std::process::Command;
    ///
    /// let mut command = Command::new("ls");
    /// if let Ok(mut child) = command.spawn() {
    ///     child.wait().expect("command wasn't running");
    ///     println!("Child has finished its execution!");
    /// } else {
    ///     println!("ls command didn't start");
    /// }
    /// ```
    ///
    ///
    #[stable(feature = "process", since = "1.0.0")]
    pub fn wait(&mut self) -> io::Result<ExitStatus> {
        drop(self.stdin.take());
        self.handle.wait().map(ExitStatus)
    }

    /// 如果子节点已经退出,则尝试收集其退出状态。
    ///
    /// 这个函数不会阻塞调用线程,只会检查子进程是否退出。
    ///
    /// 如果子节点退出了,则在 Unix 上获取进程 ID。
    /// 只要子节点已经退出,就可以保证该函数重复返回成功的退出状态。
    ///
    /// 如果子节点已经退出,则返回 `Ok(Some(status))`。
    /// 如果此时退出状态不可用,则返回 `Ok(None)`。
    /// 如果发生错误,则返回该错误。
    ///
    /// 请注意,与 `wait` 不同,此函数不会尝试丢弃 stdin。
    ///
    /// # Examples
    ///
    /// 基本用法:
    ///
    /// ```no_run
    /// use std::process::Command;
    ///
    /// let mut child = Command::new("ls").spawn().unwrap();
    ///
    /// match child.try_wait() {
    ///     Ok(Some(status)) => println!("exited with: {}", status),
    ///     Ok(None) => {
    ///         println!("status not ready yet, let's really wait");
    ///         let res = child.wait();
    ///         println!("result: {:?}", res);
    ///     }
    ///     Err(e) => println!("error attempting to wait: {}", e),
    /// }
    /// ```
    ///
    ///
    #[stable(feature = "process_try_wait", since = "1.18.0")]
    pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
        Ok(self.handle.try_wait()?.map(ExitStatus))
    }

    /// 同时等待子节点退出并收集 stdout/stderr 句柄上的所有剩余输出,并返回 `Output` 实例。
    ///
    /// 子进程的 stdin 句柄 (如果有) 将在等待之前关闭。
    /// 这有助于避免死锁: 它确保子进程在父进程等待子进程退出时不会阻止其等待父进程的输入。
    ///
    ///
    /// 默认情况下,stdin、stdout 和 stderr 都是从父级继承的。
    /// 为了将输出捕获到此 `Result<Output>` 中,必须在父级和子级之间创建新管道。
    /// 分别使用 `stdout(Stdio::piped())` 或 `stderr(Stdio::piped())`。
    ///
    /// # Examples
    ///
    /// ```should_panic
    /// use std::process::{Command, Stdio};
    ///
    /// let child = Command::new("/bin/cat")
    ///     .arg("file.txt")
    ///     .stdout(Stdio::piped())
    ///     .spawn()
    ///     .expect("failed to execute child");
    ///
    /// let output = child
    ///     .wait_with_output()
    ///     .expect("failed to wait on child");
    ///
    /// assert!(output.status.success());
    /// ```
    ///
    ///
    ///
    ///
    ///
    #[stable(feature = "process", since = "1.0.0")]
    pub fn wait_with_output(mut self) -> io::Result<Output> {
        drop(self.stdin.take());

        let (mut stdout, mut stderr) = (Vec::new(), Vec::new());
        match (self.stdout.take(), self.stderr.take()) {
            (None, None) => {}
            (Some(mut out), None) => {
                let res = out.read_to_end(&mut stdout);
                res.unwrap();
            }
            (None, Some(mut err)) => {
                let res = err.read_to_end(&mut stderr);
                res.unwrap();
            }
            (Some(out), Some(err)) => {
                let res = read2(out.inner, &mut stdout, err.inner, &mut stderr);
                res.unwrap();
            }
        }

        let status = self.wait()?;
        Ok(Output { status, stdout, stderr })
    }
}

/// 使用指定的退出代码终止当前进程。
///
/// 该函数将永远不会返回,并会立即终止当前进程。退出代码将传递到底层操作系统,并且可供其他进程使用。
///
/// 请注意,由于此函数从不返回,并且终止了该进程,因此将不运行当前栈或任何其他线程的栈上的析构函数。
/// 如果需要彻底关闭,建议仅在没有更多析构函数可以运行的已知点上调用此函数。
///
/// ## 平台特定的行为
///
/// **Unix**: 在类似 Unix 的平台上,检查父级退出代码的父进程不太可能看到 `exit` 的所有 32 位。
/// 在大多数类 Unix 平台上,仅考虑八个最低有效位。
///
/// # Examples
///
/// 由于此函数的行为与析构函数有关,因此使用该函数的常规方法是将实际的计算提取到另一个函数,并从其返回值计算退出代码:
///
///
/// ```
/// fn run_app() -> Result<(), ()> {
///     // 这里的应用逻辑
///     Ok(())
/// }
///
/// fn main() {
///     std::process::exit(match run_app() {
///         Ok(_) => 0,
///         Err(err) => {
///             eprintln!("error: {:?}", err);
///             1
///         }
///     });
/// }
/// ```
///
/// 由于 [platform-specific behavior],此示例的退出代码将是 Linux 上的 `0`,但 Windows 上的 `256`:
///
/// ```no_run
/// use std::process;
///
/// process::exit(0x0100);
/// ```
///
/// [platform-specific behavior]: #platform-specific-behavior
///
///
///
///
///
///
///
///
#[stable(feature = "rust1", since = "1.0.0")]
pub fn exit(code: i32) -> ! {
    crate::sys_common::rt::cleanup();
    crate::sys::os::exit(code)
}

/// 以异常方式终止进程。
///
/// 该函数将永远不会返回,并会以特定于平台的 "abnormal" 方式立即终止当前进程。
///
/// 请注意,由于此函数从不返回,并且终止了该进程,因此将不运行当前栈或任何其他线程的栈上的析构函数。
///
///
/// Rust IO 缓冲区 (例如,来自 `BufWriter`) 不会被刷新。
/// 同样,C 标准输入输出缓冲器 (在大多数平台上) 不会被刷新。
///
/// 这与 [`panic!`] 的默认行为相反,后者默认情况下会展开当前线程的栈并调用所有析构函数。
/// 设置 `panic="abort"` 时,无论是 `rustc` 的参数还是 crate 的 Cargo.toml,[`panic!`] 和 `abort` 都是相似的。
/// 但是,[`panic!`] 仍然会调用 [panic hook],而 `abort` 不会。
///
/// 如果需要彻底关闭,建议仅在没有更多析构函数可以运行的已知点上调用此函数。
///
/// 该进程的终止将类似于 C `abort()` 函数的终止。
/// 在 Unix 上,进程将以信号 `SIGABRT` 终止,这通常意味着 shell 打印 "Aborted"。
///
/// # Examples
///
/// ```no_run
/// use std::process;
///
/// fn main() {
///     println!("aborting");
///
///     process::abort();
///
///     // 执行永远不会到这里
/// }
/// ```
///
/// `abort` 函数会终止该进程,因此析构函数将不会在以下示例上运行:
///
/// ```no_run
/// use std::process;
///
/// struct HasDrop;
///
/// impl Drop for HasDrop {
///     fn drop(&mut self) {
///         println!("This will never be printed!");
///     }
/// }
///
/// fn main() {
///     let _x = HasDrop;
///     process::abort();
///     // 为 HasDrop 实现的析构函数永远不会运行
/// }
/// ```
///
/// [panic hook]: crate::panic::set_hook
///
///
///
///
///
///
///
///
#[stable(feature = "process_abort", since = "1.17.0")]
#[cold]
pub fn abort() -> ! {
    crate::sys::abort_internal();
}

/// 返回与此进程关联的操作系统分配的进程标识符。
///
/// # Examples
///
/// 基本用法:
///
/// ```no_run
/// use std::process;
///
/// println!("My pid is {}", process::id());
/// ```
///
///
#[stable(feature = "getpid", since = "1.26.0")]
pub fn id() -> u32 {
    crate::sys::os::getpid()
}

/// trait,用于在 `main` 函数中实现任意返回类型。
///
/// C-main 函数仅支持返回整数作为返回类型。
/// 因此,实现 `Termination` trait 的每种类型都必须转换为整数。
///
/// 默认实现将返回 `libc::EXIT_SUCCESS` 以指示成功执行。
/// 如果发生故障,则返回 `libc::EXIT_FAILURE`。
///
#[cfg_attr(not(test), lang = "termination")]
#[unstable(feature = "termination_trait_lib", issue = "43301")]
#[rustc_on_unimplemented(
    message = "`main` has invalid return type `{Self}`",
    label = "`main` can only return types that implement `{Termination}`"
)]
pub trait Termination {
    /// 被调用以获取值的表示形式作为状态码。
    /// 此状态代码返回到操作系统。
    fn report(self) -> i32;
}

#[unstable(feature = "termination_trait_lib", issue = "43301")]
impl Termination for () {
    #[inline]
    fn report(self) -> i32 {
        ExitCode::SUCCESS.report()
    }
}

#[unstable(feature = "termination_trait_lib", issue = "43301")]
impl<E: fmt::Debug> Termination for Result<(), E> {
    fn report(self) -> i32 {
        match self {
            Ok(()) => ().report(),
            Err(err) => Err::<!, _>(err).report(),
        }
    }
}

#[unstable(feature = "termination_trait_lib", issue = "43301")]
impl Termination for ! {
    fn report(self) -> i32 {
        self
    }
}

#[unstable(feature = "termination_trait_lib", issue = "43301")]
impl<E: fmt::Debug> Termination for Result<!, E> {
    fn report(self) -> i32 {
        let Err(err) = self;
        eprintln!("Error: {:?}", err);
        ExitCode::FAILURE.report()
    }
}

#[unstable(feature = "termination_trait_lib", issue = "43301")]
impl Termination for ExitCode {
    #[inline]
    fn report(self) -> i32 {
        self.0.as_i32()
    }
}