-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Strings are not passed as they are to externals #4601
Comments
Let's leave this open and tag it |
@elferherrera - the issue you linked to is marked Windows-specific. Seems like it would fix the issue you saw on Windows, but you originally saw it on macOS too right? |
I see the issue with externals in MacOS and Windows operating system. I linked to that issue for reference with scaped quotes |
I just found in a another issue that nu seems to be passing the double quotes literally to external commands that have flags with an |
Simple reproducer to show the quotes being passed through to the command: // foo.c
#include <stdio.h>
int main(int argc, char **argv) {
for (int i=1; i < argc; i++) {
puts(argv[i]);
}
}
Compared to zsh:
|
@JCallicoat I can confirm that by adding a space the external command works |
imo, passing arguments to externals should "just work". we continually have issues with it. I'd like to resolve it once and for all. I'm not sure what that resolution looks like though. |
The thing is that bash and zsh does thing differently. Bash removes all quotes before passing it to the external, zsh does it sometimes |
I'm willing to try just about anything in order to quit having complaints about external parameters not working. |
In that case I would suggest to go the bash route. It removes all quotes from the arguments to externals. For example, if I call this external like this in bash
it is received by the external like this
Notice that the quotes for |
Sounds good to me. I'm willing to try that and see how it goes. |
This PR is a complete rewrite of `run_external.rs`. The main goal of the rewrite is improving readability, but it also fixes some bugs related to argument handling and the PATH variable (fixes #6011). I'll discuss some technical details to make reviewing easier. ## Argument handling Quoting arguments for external commands is hard. Like, *really* hard. We've had more than a dozen issues and PRs dedicated to quoting arguments (see Appendix) but the current implementation is still buggy. Here's a demonstration of the buggy behavior: ```nu let foo = "'bar'" ^touch $foo # This creates a file named `bar`, but it should be `'bar'` ^touch ...[ "'bar'" ] # Same ``` I'll describe how this PR deals with argument handling. First, we'll introduce the concept of **bare strings**. Bare strings are **string literals** that are either **unquoted** or **quoted by backticks** [^1]. Strings within a list literal are NOT considered bare strings, even if they are unquoted or quoted by backticks. When a bare string is used as an argument to external process, we need to perform tilde-expansion, glob-expansion, and inner-quotes-removal, in that order. "Inner-quotes-removal" means transforming from `--option="value"` into `--option=value`. ## `.bat` files and CMD built-ins On Windows, `.bat` files and `.cmd` files are considered executable, but they need `CMD.exe` as the interpreter. The Rust standard library supports running `.bat` files directly and will spawn `CMD.exe` under the hood (see [documentation](https://doc.rust-lang.org/std/process/index.html#windows-argument-splitting)). However, other extensions are not supported [^2]. Nushell also supports a selected number of CMD built-ins. The problem with CMD is that it uses a different set of quoting rules. Correctly quoting for CMD requires using [Command::raw_arg()](https://doc.rust-lang.org/std/os/windows/process/trait.CommandExt.html#tymethod.raw_arg) and manually quoting CMD special characters, on top of quoting from the Nushell side. ~~I decided that this is too complex and chose to reject special characters in CMD built-ins instead [^3]. Hopefully this will not affact real-world use cases.~~ I've implemented escaping that works reasonably well. ## `which-support` feature The `which` crate is now a hard dependency of `nu-command`, making the `which-support` feature essentially useless. The `which` crate is already a hard dependency of `nu-cli`, and we should consider removing the `which-support` feature entirely. ## Appendix Here's a list of quoting-related issues and PRs in rough chronological order. * #4609 * #4631 * #4601 * #5846 * #5978 * #6014 * #6154 * #6161 * #6399 * #6420 * #6426 * #6465 * #6559 * #6560 [^1]: The idea that backtick-quoted strings act like bare strings was introduced by Kubouch and briefly mentioned in [the language reference](https://www.nushell.sh/lang-guide/chapters/strings_and_text.html#backtick-quotes). [^2]: The documentation also said "running .bat scripts in this way may be removed in the future and so should not be relied upon", which is another reason to move away from this. But again, quoting for CMD is hard. [^3]: If anyone wants to try, the best resource I found on the topic is [this](https://daviddeley.com/autohotkey/parameters/parameters.htm).
Describe the bug
The next command errors because the string after the filter is not passed as it is
The error received from the external is this one
How to reproduce
run external command that requires an argument with string
Expected behavior
The string is passed correctly to the argument
Screenshots
No response
Configuration
No response
Additional context
No response
The text was updated successfully, but these errors were encountered: