Skip to main content

nu_command/system/
uname.rs

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