Notable Changes
Commandsโ
In Nushell, several traditional commands have lost their original meaning or have been replaced by more modern and structured approaches. Some notable examples include:
- awk: Nushell offers native functionality for structured data manipulation, making awk largely unnecessary.
- sed: Like awk, many of sed's functions are replaced by Nushell's internal commands for string and data manipulation.
- grep: Nushell has native commands for data filtering and searching, reducing the need for traditional grep.
- find: Nushell implements its own file search version, which is more integrated with the structured data manipulation system.
- wc: Functions like line counting are performed differently in Nushell, using pipelines and native commands.
- jq and yq: With Nushell treating JSON and YAML data natively, tools like jq become less necessary.
These traditional commands like sed, grep, awk, and others still exist in Nushell, but for different reasons than in traditional shells: Nushell maintains these commands to ensure compatibility with existing scripts and workflows, gradual transition, interoperability, etc.
Flagsโ
When migrating to Nushell, one of the most striking differences is the new approach regarding commands and their flags. Users familiar with shells like Bash or Zsh may initially find the absence of traditional flags in many well-known commands strange. This change reflects Nushell's core philosophy: treat data in a structured way and offer a more simplified command syntax.
In Nushell, many commands have been redesigned to operate without flags, adopting a subcommand and pipeline-based approach. This new structure promotes the use of pipelines to filter and manipulate data, replacing traditional flags with a series of interconnected commands. This methodology, although initially different, provides a more intuitive and flexible way to interact with the system and process information.
However, as mentioned previously, the help documentation for commands is very well done, facilitating this migration.
An example would be the ps aux command that we use to see processes, which practically lost all its flags, with only -l remaining to view all columns.
~/test> ps -h
View information about system processes.
Search terms: procedures, operations, tasks, ops
Usage:
> ps {flags}
Flags:
-h, --help: Display the help message for this command
-l, --long: list all available columns for each entry
Input/output types:
โญโโโโฌโโโโโโโโโโฌโโโโโโโโโฎ
โ # โ input โ output โ
โโโโโผโโโโโโโโโโผโโโโโโโโโค
โ 0 โ nothing โ table โ
โฐโโโโดโโโโโโโโโโดโโโโโโโโโฏ
Examples:
List the system processes
> ps
List the top 5 system processes with the highest memory usage
> ps | sort-by mem | last 5
List the top 3 system processes with the highest CPU usage
> ps | sort-by cpu | last 3
List the system processes with 'nu' in their names
> ps | where name =~ 'nu'
Get the parent process id of the current nu process
> ps | where pid == $nu.pid | get ppid
It's possible to execute a command through nushell as implemented by the operating system instead of using the redesigned command.
The ls -lha command doesn't exist in nushell because the -h flag no longer exists. But if we want to invoke the native ls from the system we can use ห in front of the command. You'll see that the data returns to text form and is no longer structured.
# This searches for ls directly from /bin/ls
~/test> ^ls -lha
total 48
drwxr-xr-x@ 5 davidprata staff 160B 11 Feb 06:51 .
drwxr-x---+ 70 davidprata staff 2.2K 11 Feb 08:32 ..
-rw-r--r--@ 1 davidprata staff 15K 13 Jan 14:31 pod.yaml
-rwxr-xr-x@ 1 davidprata staff 400B 11 Feb 06:51 script.sh
The commands inside Nushell are not traditional operating system binaries, but rather an internal implementation of Nushell itself. This implementation is part of Nushell's source code and is compiled together with the shell.
Errorsโ
The way Nushell handles errors is a show in itself! Error messages are presented in a clear, concise, and highly informative manner.
Simplicity: Errors are displayed directly, without unnecessary technical jargon.Ease of understanding: Messages are formulated in accessible language, facilitating quick understanding of the problem.Useful suggestions: In many cases, Nushell goes beyond simple error notification, offering practical suggestions for resolution.Contextualization: Errors are frequently accompanied by relevant contextual information, helping to identify the origin of the problem.Visual formatting: The visual presentation of errors is well structured, using colors and formatting to highlight important information.
This intuitive approach to error handling seems to anticipate user needs, making the debugging and problem-solving process significantly more efficient and less frustrating.
~> open deploy.yaml | get spec.template.spec.container
Error: nu::shell::name_not_found
ร Name not found
โญโ[entry #8:1:43]
1 โ open deploy.yaml | get spec.template.spec.container
ยท โโโโโฌโโโโ
ยท โฐโโ did you mean 'containers'?
โฐโโโโ
~> open deploy.yaml | get spec.template.spec.containers
โญโโโโฌโโโโโโโโฌโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโฎ
โ # โ image โ name โ resources โ
โโโโโผโโโโโโโโผโโโโโโโโผโโโโโโโโโโโโโโโโโโโโค
โ 0 โ nginx โ nginx โ {record 0 fields} โ
โฐโโโโดโโโโโโโโดโโโโโโโโดโโโโโโโโโโโโโโโโโโโโฏ
# -p doesn't exist...
~> ls -lp
Error: nu::parser::unknown_flag
ร The `ls` command doesn't have flag `-p`.
โญโ[entry #9:1:6]
1 โ ls -lp
ยท โฌ
ยท โฐโโ unknown flag
โฐโโโโ
help: Available flags: --help(-h), --all(-a), --long(-l), --short-names(-s), --full-paths(-f), --du(-d), --directory(-D),
--mime-type(-m), --threads(-t). Use `--help` for more information.
~> echo $LANG
Error: nu::parser::env_var_not_var
ร Use $env.LANG instead of $LANG.
โญโ[entry #30:1:6]
1 โ echo $LANG
ยท โโโฌโโ
ยท โฐโโ use $env.LANG instead of $LANG
โฐโโโโ
~> echo $env.LANG
pt_BR.UTF-8
Environment Variablesโ
In Nushell, the env command is an external system command, not specific to Nushell, which is why:
- It shows environment variables in the traditional key=value format.
- The output is plain text, not structured.
The $env command is an internal Nushell command.
- It shows environment variables as a data structure.
- The output is structured, typically in table format.
The difference reflects Nushell's philosophy of treating data in a structured way. When you use $env, you're directly accessing Nushell's environment object, which maintains variables in a richer and more manipulable format.
In most cases, $env in Nushell and the traditional env command will show the same environment variables with the same values. However, there may be some differences:
$envin Nushell generally includes all variables shown by traditionalenv.$envmay contain additional Nushell-specific variables that don't appear in traditionalenv.- Some variables may be presented differently in
$env. For example, PATH may be shown as a list in Nushell, while in traditionalenvit's a colon-separated string. - Nushell may add or modify some environment variables during initialization.
Just to compare quickly...
~> env | wc -l
56
# It's necessary to format the $env output to have everything divided into lines and columns.
~> $env | transpose key value | length
62
We can observe that we have more, but the 56 we found are within the 62.
Nushell inherits environment variables from the parent process that started it.
This approach offers several advantages:
Organization: All environment variables are grouped in a single location, facilitating management.Clarity: The$env.prefix makes it explicit that you're dealing with an environment variable, not a local or global variable.Structure:$envis treated as a structured object, allowing more advanced and consistent operations.Typing: Variables within$envcan maintain their original data types, not being limited to just strings.Safety: This structure helps prevent accidental conflicts with other variables in the shell.
Environment variables and Nushell-specific settings are stored in the $env object. General environment variables are accessed directly through $env, while Nushell settings are maintained in $env.config. We'll explore $env.config in more detail when we address advanced Nushell optimization and customization, allowing us to take full advantage of it.
The
$envobject encompasses not only standard environment variables, but also Nushell-specific settings and other internal variables. This explains why$envshows 62 entries, while theenvcommand shows only 56.
The path variable that was previously separated by : now has a structure that shows each path as an item.
~/test> $env.PATH
# We'll talk about this later.
~/test> $env.config
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโฎ
โ filesize โ {record 2 fields} โ
โ table โ {record 8 fields} โ
โ ls โ {record 2 fields} โ
โ color_config โ {record 59 fields} โ
โ footer_mode โ 25 โ
โ float_precision โ 2 โ
โ recursion_limit โ 50 โ
โ use_ansi_coloring โ true โ
โ completions โ {record 7 fields} โ
โ edit_mode โ emacs โ
โ history โ {record 4 fields} โ
โ keybindings โ [list 0 items] โ
โ menus โ [list 0 items] โ
โ hooks โ {record 5 fields} โ
โ rm โ {record 1 field} โ
โ shell_integration โ {record 7 fields} โ
โ buffer_editor โ vim โ
โ show_banner โ false โ
โ bracketed_paste โ true โ
โ render_right_prompt_on_last_line โ false โ
โ explore โ {record 0 fields} โ
โ cursor_shape โ {record 3 fields} โ
โ datetime_format โ {record 2 fields} โ
โ error_style โ fancy โ
โ display_errors โ {record 2 fields} โ
โ use_kitty_protocol โ false โ
โ highlight_resolved_externals โ false โ
โ plugins โ {record 0 fields} โ
โ plugin_gc โ {record 2 fields} โ
Some Conveniencesโ
mkdir now has -p automatically
mkdir test1/test2/test3
tree test1/
test1/
โโโ test2
โโโ test3
No need to type cd to change folders. Type the path and it goes directly.
> pwd
/home/david/test
> test1/
> pwd
/home/david/test/test1
>..
>pwd
/home/david/test
Some Differencesโ
The > to redirect output somewhere doesn't work.
# This doesn't work
> echo "david" > file.txt
โญโโโโฌโโโโโโโโโโโฎ
โ 0 โ david โ
โ 1 โ > โ
โ 2 โ file.txt โ
โฐโโโโดโโโโโโโโโโโฏ
# file.txt was not even created
> ls
โญโโโโฌโโโโโโโโฌโโโโโโโฌโโโโโโโฌโโโโโโโโโโโโโโโโโฎ
โ # โ name โ type โ size โ modified โ
โโโโโผโโโโโโโโผโโโโโโโผโโโโโโโผโโโโโโโโโโโโโโโโโค
โ 0 โ test3 โ dir โ 64 B โ 10 minutes ago โ
โฐโโโโดโโโโโโโโดโโโโโโโดโโโโโโโดโโโโโโโโโโโโโโโโโฏ
If you want to do this, let's use save.
>echo "david" | save file.txt
> ls
โญโโโโฌโโโโโโโโโโโฌโโโโโโโฌโโโโโโโฌโโโโโโโโโโโโโโโโโฎ
โ # โ name โ type โ size โ modified โ
โโโโโผโโโโโโโโโโโผโโโโโโโผโโโโโโโผโโโโโโโโโโโโโโโโโค
โ 0 โ file.txt โ file โ 5 B โ now โ
โ 1 โ test3 โ dir โ 64 B โ 11 minutes ago โ
But why doesn't this work? It's trying to compare things
4 > 10
false
Some things seem the same but are different. While a echo "Hello my friend" command is throwing the value to output, nushell is returning from a command, so we can do this.
"Hello my friend" == (echo "Hello my friend")
true
Even though it's showing, it's actually showing the function return and this won't go to the console, so using echo in a nu script thinking it will print to the console doesn't work. If you want this, we need to use print.
print "Hello my friend"
Hello my friend
Background tasks like in bash for example my_long_command & are not yet supported by nushell. There are solutions using Pueue, take a look later, but I practically don't use it in my daily work. When I need something like this, I simply open another terminal. My intention is to use Nushell for productivity.
We'll learn these things over time.
It's worth noting some differences with bash.
Over time, using the documentation better, we'll learn more. For now, I believe this is enough to help us adapt to Nushell.