Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation: A "Coming from Perl" section #1843

Open
incansvl opened this issue Mar 23, 2025 · 6 comments
Open

Documentation: A "Coming from Perl" section #1843

incansvl opened this issue Mar 23, 2025 · 6 comments
Labels
enhancement New feature or request

Comments

@incansvl
Copy link

incansvl commented Mar 23, 2025

Related problem

The "Coming from " sections of the Nushell book are a great idea, but there is an obvious "other language" missing- Perl.

As a solution that aims to bridge the gap between shells and programming languages the Pathologically Eclectic Rubbish Lister (PERL) seems to me the natural ancestor/competitor of Nushell. Perl may be long in the tooth but it is still a very widely used tool on Linux / Unix based systems, and has a lot of features designed specifically to make it work well as a "glue" language.

It's not obvious (at least to me as a user new to Nushell) how some of the things Perl can do can be accomplished in Nushell, some specific "getting started" help would be useful.

Describe the solution you'd like

A documentation section on "Coming from Perl" could help open up Nushell to areas where Perl has been the "swiss army knife" of system automation for years.

As an example, it would be particularly helpful to have idiomatic Nushell alternatives for the Perl "special variables" including-

$0    $PROGRAM_NAME        Pathname of the current script
$$    $PID                 The pid of the process running the current script
$^T   $BASETIME            Timestamp when the current process started
$<    $UID                 Real user ID (uid) of this process
$>    $EUID                Effective user ID of this process
$(    $GID                 Real group ID
$)    $EGID                Effective group ID
$!    $ERRNO / $OS_ERROR   Number or text of the error from the last system call
$?    $CHILD_ERROR         Status returned by the last child process

Describe alternatives you've considered

No response

Additional context and details

No response

@incansvl incansvl added the enhancement New feature or request label Mar 23, 2025
@NotTheDr01ds NotTheDr01ds transferred this issue from nushell/nushell Mar 23, 2025
@NotTheDr01ds
Copy link
Contributor

I think that's a great idea - I've moved this over to our Doc repo where the PR will need to be as well.

I also think that you have the right idea - this would be better as a page of its own rather than adding it to the rather unwieldy monolithic mapping table.

Our docs are all user contributions, so hopefully someone can chime in who has the expertise in both Perl and Nushell to help out.

If you'd like to start a page and ask in Discord (or possibly Stack Exchange) about specific items, perhaps we can collectively create something.

For the items you asked about ... Well, I was answering them but had a reboot and lost it :-/

I'll try to fill something in in a bit.

@incansvl
Copy link
Author

I found a couple of answers in the responses (quite possibly yours?) to nushell/nushell#4564

Perl / Bash        Nushell
-----------        -------
$$                 $nu.pid
$?                 $env.LAST_EXIT_CODE
$0                 $env.PROCESS_PATH

I would be happy to initiate a documentation page, but i'll need to work out the process.

@NotTheDr01ds
Copy link
Contributor

NotTheDr01ds commented Mar 24, 2025

index Short Long Description
1 $0 $PROGRAM_NAME Pathname of the current script
2 $$ $PID The pid of the process running the current script
3 $^T $BASETIME Timestamp when the current process started
4 $< $UID Real user ID (uid) of this process
5 $> $EUID Effective user ID of this process
6 $( $GID Real group ID
7 $) $EGID Effective group ID
8 $! $ERRNO / $OS_ERROR Number or text of the error from the last system call
9 $? $CHILD_ERROR Status returned by the last child process
  1. For a script, yes, $env.PROCESS_PATH - Also (as mentioned in the issue you linked) keep in mind $env.CURRENT_FILE for modules and sourced files. In Nushell, most use-cases tend towards custom commands in source/modules rather than scripts.

  2. Yes - Easy enough, $nu.pid

  3. Can be obtained (at least on Linux/Unix) as a datetime with:

    ps -l | where pid == $nu.pid | get start_time.0
  4. As a cross-platform shell, there are some things we just don't implement directory, especially when there are system-specific binaries that handle this. So for 4-7 here I would point to the /usr/bin/id command. For instance, id -g -r to get the real group ID.


  1. I'm not sure this is applicable to Nushell since you can't invoke system commands with Nushell.

  2. Yes, $env.LAST_EXIT_CODE is available, but a few months ago we also implemented the ability to use try/catch handling as well, and this works for both externals as well as internal commands. For instance:

    try { ^ls file-that-does-not-exist } catch {|e| print $e.exit_code }

    That often will provide better flow control than checking $env.LAST_EXIT_CODE.

@NotTheDr01ds
Copy link
Contributor

but i'll need to work out the process

Really, really short version (the stuff I had to figure out my first time):

  • Fork this repo and clone it locally, of course
  • The site is built statically using Vuepress, but you can run it dynamically locally (assuming Node 20 or later) with:
    cd <repo>
    npm install
    npm run dev
  • Pages are added to the doc/sidebar via .vuepress/configs/sidebar/en.ts

@incansvl
Copy link
Author

Thanks for the helpful comments, a good chunk of the answers are right there. A couple of thoughts or questions-

1. ... In Nushell, most use-cases tend towards custom commands in source/modules rather than scripts.

Does this imply the user is using Nushell as their default login shell, and then invoking custom commands in a kind of "personal DSL shell" environment?

For me at this point I see Nushell more as a potential replacement for Perl than a replacement for bash. I never used Perl as an interactive shell, but instead as a tool to write utility scripts and small tools in something with all the capability of a shell, but also more of the approach of a "real" programming language with, in the case of Perl, access to an enormous module library (CPAN) covering just about any need you could think of.

Similarly on Windows, I wouldn't bother with PowerShell just to open a terminal and list a few files. But CMD is a truly horrible thing to write scripts in, and then the verbosity of PowerShell is worth it because of the power of the language, and the deep (although sadly not complete) access to the Windows system.

2. Yes - Easy enough, `$nu.pid`

3. Can be obtained (at least on Linux/Unix) as a `datetime` with:
   ps -l | where pid == $nu.pid | get start_time.0

👍

4. As a cross-platform shell, there are some things we just don't implement directory, especially when there are system-specific binaries that handle this.  So for 4-7 here I would point to the `/usr/bin/id` command.  For instance, `id -g -r` to get the real group ID.

Yes, fair enough. Perl is very "Unix native". As Nushell is aimed at being cross-platform from the outset it seems reasonable to reply on external tools to access platform-specific stuff like this.

8. I'm not sure this is applicable to Nushell since you can't invoke system commands with Nushell.

Interesting, so there will be some things you can do in Perl that just aren't possible in Nushell unless there happens to be a specific command built into the language. Presumably Nushell allows for library modules written in a lower-level language (e.g. Rust) in the same way that Perl has "native" modules written in C, so low-level interfaces (system calls, or something like a graphics library interface) could be implemented FOR nushell, but not IN nushell.

9. Yes, `$env.LAST_EXIT_CODE` is available, but a few months ago we also implemented the ability to use `try`/`catch` handling as well, and this works for both externals as well as internal commands.  For instance:
   try { ^ls file-that-does-not-exist } catch {|e| print $e.exit_code }
   That often will provide better flow control than checking `$env.LAST_EXIT_CODE`.

Thanks. That does sound rather nicer, although I know there's a lot of controversy around error handling models in languages, and try/catch is not immune.

@NotTheDr01ds
Copy link
Contributor

NotTheDr01ds commented Mar 25, 2025

Does this imply the user is using Nushell as their default login shell, and then invoking custom commands in a kind of "personal DSL shell" environment?

Perhaps not as their default/login shell to start. For instance, I used Fish for about 4 years before I discovered Nushell, and I kept Fish as my default shell for around a year before switching over "fully". During that transition, I would run Fish for navigation/external commands (e.g., git or ssh), filesystem commands, etc. And I'd run Nushell interactively when I needed to work with my data.

I get the feeling that's the normal route for most users. The biggest reason for this is that scripts cannot output structured data, at least not today, and probably never when running inside another shell.

A "personal DSL shell" is a great way of describing it -- A custom command can output structured data, so you can further refine the output on the command-line. Then, often, turn around and update the custom command.

And, at some point for many users (obviously myself included), it just becomes natural to switch to Nushell entirely. It typically comes when you discover you just start up your existing shell and immediately type nu way ... too ... much ;-).

Interesting, so there will be some things you can do in Perl that just aren't possible in Nushell unless there happens to be a specific command built into the language. Presumably Nushell allows for library modules written in a lower-level language (e.g. Rust) in the same way that Perl has "native" modules written in C, so low-level interfaces (system calls, or something like a graphics library interface) could be implemented FOR nushell, but not IN nushell.

Yes, plugins in Nushell (also, the developer doc) can be written in any language (but typically Rust) and can both make lower-level calls as well as participate in Nushell as first-class commands, including structured data, error handling, types, etc.

although I know there's a lot of controversy around error handling models in languages, and try/catch is not immune.

Agreed - It's not perfect, and I was personally somewhat skeptical when we first implemented the ability to handle external errors in try/catch, but I think it's turned out pretty ergonomically.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants