-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
rsync globs behave differently in Nushell than in Bash #4609
Comments
I'm not sure if this is just a glob issue or not. It seems like it's not properly passing parameters to rsync correctly. I tried a minimal example and I still get different results from bash:
On bash:
My nushell version:
|
The problem seems to be that nu is passing the double quotes to rsync when the --exclude flag is using an
So it gets the exclude pattern including the quotes and Using the flag with
Bash and zsh both consume the quotes and just pass |
@JCallicoat Seems to work for that example - but globs still seem to be an issue with or without the equals sign. In my tests it only seems to pick up one file that matches the glob instead of all.
I don't use rsync enough to figure out why it's including test2.txt and not test1.txt but I suspect it's because the expansion of the command is:
which seems like an unorthodox usage of rsync |
@lukexor Can confirm here. That seems to be the same issue with globs expanding in quoted strings you opened in #4631 Just running a little c program that prints out the arguments shows the different behaviors right now. Quoted and equals passes through quotes literally:
Quoted and space expands glob to file list:
Both of those break rsync in different ways. Unquoted and equals passes through glob literally:
This works correctly with rsync in my testing. The different behaviors are pretty unexpected and non-intuitive. Edit: FWIW, here's zsh in all three cases:
|
The form without |
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
I used
rsync -avhz name@server:/home/name/some/path/ destination --include="*/" --include="*.pth" --exclude="*"
which did not fetch me only.pth
files but all the files.I need to elaborate on it more when I have the time, just wanted to log this in since there might be some misbehavior.
How to reproduce
Expected behavior
The
rsync
globs should work the same way in Nushell and in Bash.Screenshots
No response
Configuration
Additional context
No response
The text was updated successfully, but these errors were encountered: