Skip to main content

nu_command/system/
uname.rs

1use nu_engine::command_prelude::*;
2use nu_protocol::{Value, record};
3use uucore::{localized_help_template, translate};
4
5#[derive(Clone)]
6pub struct UName;
7
8impl Command for UName {
9    fn name(&self) -> &str {
10        "uname"
11    }
12
13    fn signature(&self) -> Signature {
14        Signature::build("uname")
15            .input_output_types(vec![(Type::Nothing, Type::table())])
16            .category(Category::System)
17    }
18
19    fn description(&self) -> &str {
20        "Print certain system information using uutils/coreutils uname."
21    }
22
23    fn search_terms(&self) -> Vec<&str> {
24        // add other terms?
25        vec!["system", "coreutils"]
26    }
27
28    fn is_const(&self) -> bool {
29        true
30    }
31
32    fn run(
33        &self,
34        _engine_state: &EngineState,
35        _stack: &mut Stack,
36        call: &Call,
37        _input: PipelineData,
38    ) -> Result<PipelineData, ShellError> {
39        run_uname(call)
40    }
41
42    fn run_const(
43        &self,
44        _working_set: &StateWorkingSet,
45        call: &Call,
46        _input: PipelineData,
47    ) -> Result<PipelineData, ShellError> {
48        run_uname(call)
49    }
50
51    fn examples(&self) -> Vec<Example<'_>> {
52        vec![Example {
53            description: "Print all information",
54            example: "uname",
55            result: None,
56        }]
57    }
58}
59
60fn run_uname(call: &Call) -> Result<PipelineData, ShellError> {
61    // setup the uutils error translation
62    let _ = localized_help_template("uname");
63
64    let span = call.head;
65    // Simulate `uname -all` is called every time
66    let opts = uu_uname::Options {
67        all: true,
68        kernel_name: false,
69        nodename: false,
70        kernel_release: false,
71        kernel_version: false,
72        machine: false,
73        processor: false,
74        hardware_platform: false,
75        os: false,
76    };
77    let output = uu_uname::UNameOutput::new(&opts).map_err(|e| ShellError::GenericError {
78        error: format!("{e}"),
79        msg: translate!(&e.to_string()),
80        span: None,
81        help: None,
82        inner: Vec::new(),
83    })?;
84    let outputs = [
85        output.kernel_name,
86        output.nodename,
87        output.kernel_release,
88        output.kernel_version,
89        output.machine,
90        output.os,
91    ];
92    let outputs = outputs
93        .iter()
94        .map(|name| {
95            Ok(name
96                .as_ref()
97                .ok_or("unknown")
98                .map_err(|_| ShellError::NotFound { span })?
99                .to_string_lossy()
100                .into_owned())
101        })
102        .collect::<Result<Vec<String>, ShellError>>()?;
103    Ok(PipelineData::value(
104        Value::record(
105            record! {
106                "kernel-name" => Value::string(outputs[0].clone(), span),
107                "nodename" => Value::string(outputs[1].clone(), span),
108                "kernel-release" => Value::string(outputs[2].clone(), span),
109                "kernel-version" => Value::string(outputs[3].clone(), span),
110                "machine" => Value::string(outputs[4].clone(), span),
111                "operating-system" => Value::string(outputs[5].clone(), span),
112            },
113            span,
114        ),
115        None,
116    ))
117}