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

Allow offering dynamic script output for download #251

Draft
wants to merge 12 commits into
base: master
Choose a base branch
from

Conversation

soenkehahn
Copy link
Collaborator

@casey: I was wrong about how processes get executed on linux: The kernel is capable of running scripts and binaries (e.g. ELF binaries), but in the case of scripts, they have to start with #!. So the kernel will not fall back on any shell, if the hashbang is missing. You can run scripts that don't start with #! from e.g. bash, and that will work by falling back on some shell, but that behavior is implemented in the shells you're using for that. (And apparently the exact behavior (e.g. which shell to use) depends on the parent shell being used.)

So this PR right now implements the following logic: When the given script starts with #! it is executed unmodified. If it doesn't a hashbang line is added (#!/usr/bin/sh). Judging from the tests that seems to be the behavior we want, but it's a bit magical.

The PR still needs to be cleaned up a lot, but I wanted to get your feedback early.

@casey
Copy link
Collaborator

casey commented Nov 1, 2021

@casey: I was wrong about how processes get executed on linux: The kernel is capable of running scripts and binaries (e.g. ELF binaries), but in the case of scripts, they have to start with #!. So the kernel will not fall back on any shell, if the hashbang is missing. You can run scripts that don't start with #! from e.g. bash, and that will work by falling back on some shell, but that behavior is implemented in the shells you're using for that. (And apparently the exact behavior (e.g. which shell to use) depends on the parent shell being used.)

I think I'm still a little confused about what the behavior is, and where the inconsistency is from. What you're saying is when you do ./foo in bash and foo is a text file that doesn't start with a #!, then it's bash that chooses the shell to run it with, not the kernel? What happens if you try to run it with std::process::Command::new("./script")? (I.e. with no intermediate shell.)

On macOS, running a text file with no shebang with std::process::Command::new seems to work. I think it uses /bin/sh, but I'm not sure how it makes that decision. (/bin/sh on macOS is bash.)

I think adding a shebang automatically might not be desirable. It would make it unclear what was running a script without reading documentation, and it would mess up line numbers in error messages. Also if a user misspelled a shebang, i.e. added !#/usr/bin/env, we would add our own, which would be confusing.

I think it would probably be okay to just chmod +x the script and run it, and let the user add the #! if their system requires it.

src/config.rs Outdated Show resolved Hide resolved
tokio::fs::write(&script_file, source).await.expect("fixme");
run!(%"chmod +x", &script_file);
run!(%"cat", &script_file);
let output = tokio::process::Command::new(script_file)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessary to do now, but we should remember to check the status code of the script. Not sure what to do if it fails.

Co-authored-by: Casey Rodarmor <[email protected]>
@soenkehahn
Copy link
Collaborator Author

I think I'm still a little confused about what the behavior is, and where the inconsistency is from. What you're saying is when you do ./foo in bash and foo is a text file that doesn't start with a #!, then it's bash that chooses the shell to run it with, not the kernel? What happens if you try to run it with std::process::Command::new("./script")? (I.e. with no intermediate shell.)

I get:

[src/main.rs:2] std::process::Command::new("./foo").output() = Err(
    Os {
        code: 8,
        kind: Uncategorized,
        message: "Exec format error",
    },
)

On macOS, running a text file with no shebang with std::process::Command::new seems to work. I think it uses /bin/sh, but I'm not sure how it makes that decision. (/bin/sh on macOS is bash.)

Weird.

I think adding a shebang automatically might not be desirable. It would make it unclear what was running a script without reading documentation, and it would mess up line numbers in error messages. Also if a user misspelled a shebang, i.e. added !#/usr/bin/env, we would add our own, which would be confusing.

I think it would probably be okay to just chmod +x the script and run it, and let the user add the #! if their system requires it.

Yeah, good points. I think that sounds right.

@casey casey changed the title Allow to offer dynamic script output for download Allow offering dynamic script output for download Nov 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants