# \[Shell\] Backslash within double quotes #YT5

**URL:** <https://forum.codecrafters.io/t/shell-backslash-within-double-quotes-yt5/4026>\
**Category:** Challenges\
**Tags:** challenge:shell\
**Created:** [January 7, 2025, 6:04pm UTC](https://forum.codecrafters.io/t/shell-backslash-within-double-quotes-yt5/4026 "2025-01-07T18:04:33Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![stanykey](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/stanykey/32/4070_2.png) [@stanykey](https://forum.codecrafters.io/u/stanykey)\
**Post date:** [January 7, 2025, 6:04pm UTC](https://forum.codecrafters.io/t/shell-backslash-within-double-quotes-yt5/4026/1 "2025-01-07T18:04:33Z")

</div>

I’m stuck on Stage #GU3

My code passes GU3, and regression for LE5, but fails on YT5. I’ve reworked the way I parse arguments, so it might be my fault, but I’m curious about logs:

```plaintext
remote: [tester::#YT5] Writing file "/tmp/quz/f\n55" with content "grape pineapple."
remote: [tester::#YT5] Writing file "/tmp/quz/f\69" with content "strawberry orange."
remote: [tester::#YT5] Writing file "/tmp/quz/f'\'19" with content "orange strawberry."
remote: [your-program] $ cat "/tmp/quz/f\n55" "/tmp/quz/f\69" "/tmp/quz/f'\'19"
remote: [your-program] /usr/bin/cat: '/tmp/quz/f'$'\n''55': No such file or directory
remote: [tester::#YT5] Output does not match expected value.
remote: [tester::#YT5] Expected: "grape pineapple.strawberry orange.orange strawberry."
remote: [tester::#YT5] Received: "/usr/bin/cat: '/tmp/quz/f'$'\n''55': No such file or directory"
remote: [your-program] strawberry orange.orange strawberry.
remote: [your-program] cat execution error: Command failed with exit code 1

```

when I try to this input (replace `cat` with `echo`), I get the next output, and it seems rights

```plaintext
$ echo "/tmp/quz/f\n55" "/tmp/quz/f\69" "/tmp/quz/f'\'19"
/tmp/quz/f
55 /tmp/quz/f\69 /tmp/quz/f'\'19
$ 

```

so I need a little explanation about what is real input for this test or might u have issue in tester

if we speak about **Stage #YT5 (Quoting - Backslash outside quotes)** then it works as expected or not?:

```plaintext
$ echo /tmp/quz/f\n55 /tmp/quz/f\69 /tmp/quz/f'\'19       
/tmp/quz/fn55 /tmp/quz/f69 /tmp/quz/f'19
$ 

```

here my tests:

```rust
#[cfg(test)]
mod tests {
    #[test]
    fn test_parse_basic() {
        assert_eq!(super::parse(""), Vec::<String>::new());
        assert_eq!(super::parse("arg1 arg2 arg3"), vec!["arg1", "arg2", "arg3"]);
        assert_eq!(super::parse(" arg1 arg2 "), vec!["arg1", "arg2"]);
    }

    #[test]
    fn test_parse_with_single_quotes() {
        assert_eq!(
            super::parse("'only one quoted arg'"),
            vec!["only one quoted arg"]
        );

        assert_eq!(
            super::parse("'/tmp/file name' '/tmp/file name with spaces'"),
            vec!["/tmp/file name", "/tmp/file name with spaces"]
        );

        assert_eq!(
            super::parse("'/tmp/file name' yahoo '/tmp/file name with spaces'"),
            vec!["/tmp/file name", "yahoo", "/tmp/file name with spaces"]
        );
    }

    #[test]
    fn test_parse_with_double_quotes() {
        assert_eq!(
            super::parse(r#""only one quoted arg""#),
            vec!["only one quoted arg"]
        );

        assert_eq!(
            super::parse(r#""/tmp/file name" "/tmp/file name with spaces""#),
            vec!["/tmp/file name", "/tmp/file name with spaces"]
        );

        assert_eq!(
            super::parse(r#""/tmp/file name" yahoo "/tmp/file name with spaces""#),
            vec!["/tmp/file name", "yahoo", "/tmp/file name with spaces"]
        );

        assert_eq!(
            super::parse(r#""/tmp/qux/"f 96""#),
            vec!["/tmp/qux/f", "96"]
        )
    }

    #[test]
    fn test_parse_with_mixed_quotes_1() {
        assert_eq!(
            super::parse(r#""'only one quoted arg'""#),
            vec!["'only one quoted arg'"]
        );

        assert_eq!(
            super::parse(r#"'"only one quoted arg"'"#),
            vec!["\"only one quoted arg\""]
        );

        assert_eq!(
            super::parse(r#"'"/tmp/file name"' "'/tmp/file name with spaces'""#),
            vec![r#""/tmp/file name""#, "'/tmp/file name with spaces'"]
        );
    }

    #[test]
    fn test_parse_with_mixed_quotes_2() {
        assert_eq!(
            super::parse(r#""'only" one "quoted arg'""#),
            vec!["'only", "one", "quoted arg'"]
        );
    }

    #[test]
    fn test_parse_with_backslashes_outside_quotes() {
        assert_eq!(
            super::parse(r#"world\ \ \ \ \ \ script"#),
            vec!["world script"]
        );
        assert_eq!(super::parse(r#"before\nafter"#), vec!["beforenafter"]);
        assert_eq!(
            super::parse(r#"\'\"script world\"\'"#),
            vec![r#"'"script"#, r#"world"'"#]
        );
    }

    #[test]
    fn test_parse_with_backslashes_within_single_quotes() {
        assert_eq!(
            super::parse("'shell\\\\\\nscript'"),
            vec!["shell\\\\\\nscript"]
        );
        assert_eq!(
            super::parse("'example\\\"testhello\\\"shell'"),
            vec!["example\\\"testhello\\\"shell"]
        );
    }

    #[test]
    fn test_parse_with_backslashes_within_double_quotes() {
        assert_eq!(
            super::parse(r#""hello\"insidequotes"script\""#),
            vec![r#"hello"insidequotesscript""#]
        );
        assert_eq!(super::parse(r#""/tmp/bar/f\n99""#), vec!["/tmp/bar/f\n99"]);
    }
}

```

---

<div class="post-metadata">

**Author:** ![stanykey](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/stanykey/32/4070_2.png) [@stanykey](https://forum.codecrafters.io/u/stanykey)\
**Post date:** [January 7, 2025, 8:45pm UTC](https://forum.codecrafters.io/t/shell-backslash-within-double-quotes-yt5/4026/2 "2025-01-07T20:45:45Z")

</div>

I found one issue: my code consumes opening quotes when parsing a ‘basic’ string. Let’s see the results after I fix it.

---

<div class="post-metadata">

**Author:** ![andy1li](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/andy1li/32/10_2.png) [@andy1li](https://forum.codecrafters.io/u/andy1li)\
**Post date:** [January 7, 2025, 9:29pm UTC](https://forum.codecrafters.io/t/shell-backslash-within-double-quotes-yt5/4026/3 "2025-01-07T21:29:10Z")

</div>

Hi @stanykey, let us know how the fix works out!

---

<div class="post-metadata">

**Author:** ![stanykey](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/stanykey/32/4070_2.png) [@stanykey](https://forum.codecrafters.io/u/stanykey)\
**Post date:** [January 7, 2025, 9:51pm UTC](https://forum.codecrafters.io/t/shell-backslash-within-double-quotes-yt5/4026/4 "2025-01-07T21:51:29Z")

</div>

I fixed behavior for **Stage #YT5 (Quoting - Backslash outside quotes)**

```plaintext
$ echo /tmp/quz/f\n55 /tmp/quz/f\69 /tmp/quz/f'\'19
/tmp/quz/fn55 /tmp/quz/f69 /tmp/quz/f\19
$ echo 'before'"after" test'\\\\\'"19"
beforeafter test\\\\\19
$

```

but the tester fails my code on the ‘same’ test

```auto
remote: [tester::#YT5] Writing file "/tmp/qux/f\n73" with content "strawberry banana."
remote: [tester::#YT5] Writing file "/tmp/qux/f\43" with content "strawberry orange."
remote: [tester::#YT5] Writing file "/tmp/qux/f'\'97" with content "pineapple blueberry."
remote: [your-program] $ cat "/tmp/qux/f\n73" "/tmp/qux/f\43" "/tmp/qux/f'\'97"
remote: [your-program] /usr/bin/cat: '/tmp/qux/f'$'\n''73': No such file or directory
remote: [tester::#YT5] Output does not match expected value.
remote: [tester::#YT5] Expected: "strawberry banana.strawberry orange.pineapple blueberry."
remote: [tester::#YT5] Received: "/usr/bin/cat: '/tmp/qux/f'$'\n''73': No such file or directory"
remote: [your-program] strawberry orange.pineapple blueberry.
remote: [your-program] cat execution error: Command failed with exit code 1
remote: [your-program] $

```

here are my outputs for the problematic path:

```auto
$ echo /tmp/qux/f\n73
/tmp/qux/fn73
$ echo "/tmp/qux/f\n73" 
/tmp/qux/f
73
$ echo '/tmp/qux/f\n73' 
/tmp/qux/f\n73
$ 

```

my results are equal to the native zsh outputs, so we are back to the initial statement:

- or the tester doesn’t show original input, and I can’t figure out where an issue in my code
- or the tester has a bug

---

<div class="post-metadata">

**Author:** ![stanykey](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/stanykey/32/4070_2.png) [@stanykey](https://forum.codecrafters.io/u/stanykey)\
**Post date:** [January 7, 2025, 9:54pm UTC](https://forum.codecrafters.io/t/shell-backslash-within-double-quotes-yt5/4026/5 "2025-01-07T21:54:24Z")

</div>

I guess the real input somethin like this

```auto
echo /tmp/qux/f\\n73

```

right? if yes then the test should be like this:

```rust
assert_eq!(super::parse(r#"file\\n19"#), vec!["file\n19"]);

```

right?

---

<div class="post-metadata">

**Author:** ![stanykey](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/stanykey/32/4070_2.png) [@stanykey](https://forum.codecrafters.io/u/stanykey)\
**Post date:** [January 9, 2025, 10:14am UTC](https://forum.codecrafters.io/t/shell-backslash-within-double-quotes-yt5/4026/7 "2025-01-09T10:14:09Z")

</div>

@andy1li could you help with input?

I don’t want to watch examples of code since I want to try to figure it out myself, but it looks like I need to do two-pass parsing, which probably today shells do by default without explicit the `-e` option

---

<div class="post-metadata">

**Author:** ![andy1li](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/andy1li/32/10_2.png) [@andy1li](https://forum.codecrafters.io/u/andy1li)\
**Post date:** [January 9, 2025, 12:49pm UTC](https://forum.codecrafters.io/t/shell-backslash-within-double-quotes-yt5/4026/8 "2025-01-09T12:49:57Z")

</div>

@stanykey The issue seems related to how `std::process::Command` expects newlines to be passed in.

Right now your code is interpreting `"\n"` (a backslash and `n`) as actual newlines.

If newlines were converted back to `"\\n"` (a backslash and `n`), the tests could pass successfully:

 ![image](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/2X/e/ebae591a46df45c5ea83f3fd79d66ec812a5c8d7.png)

 ![image](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/2X/a/abeec9da910e5f084b487eed079eef87fa22c17d.png)

---

<div class="post-metadata">

**Author:** ![stanykey](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/stanykey/32/4070_2.png) [@stanykey](https://forum.codecrafters.io/u/stanykey)\
**Post date:** [January 9, 2025, 1:51pm UTC](https://forum.codecrafters.io/t/shell-backslash-within-double-quotes-yt5/4026/10 "2025-01-09T13:51:22Z")

</div>

Oh, I forgot about the fact that `system::Command` also does similar processing for `args`

Thanks for the help, @andy1li

---

<div class="post-metadata">

**Author:** ![pnicto](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/pnicto/32/1618_2.png) [@pnicto](https://forum.codecrafters.io/u/pnicto)\
**Post date:** [January 9, 2025, 3:44pm UTC](https://forum.codecrafters.io/t/shell-backslash-within-double-quotes-yt5/4026/11 "2025-01-09T15:44:41Z")

</div>

I have a question regarding the same. Shouldn’t the \n when in double quotes be treated as a new line? I believe the first path to be an invalid path. My code is also failing on the same test case.

EDIT: I know this screenshot is for an earlier stage(#GU3) but with reference to that wouldn’t the \n when surrounded with double quotes be treated a newline for the test case here?

 ![-1973078381581615637](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/2X/5/54c3dfeae188d65299c6757d6968736e25ed2ba2.png)

---

<div class="post-metadata">

**Author:** ![stanykey](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/stanykey/32/4070_2.png) [@stanykey](https://forum.codecrafters.io/u/stanykey)\
**Post date:** [January 9, 2025, 7:38pm UTC](https://forum.codecrafters.io/t/shell-backslash-within-double-quotes-yt5/4026/12 "2025-01-09T19:38:07Z")

</div>

According to documentation, it’s treated as a new line if it’s quoted (no matter whether single or double). In my case, `system::Command::args` did second pass processing of the input string, and it caused the issue with the `cat` call, so check how you pass args because u may see the right result with `echo` but then have the wrong with external command due to some API also does argument processing

---

<div class="post-metadata">

**Author:** ![andy1li](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/andy1li/32/10_2.png) [@andy1li](https://forum.codecrafters.io/u/andy1li)\
**Post date:** [January 10, 2025, 12:00am UTC](https://forum.codecrafters.io/t/shell-backslash-within-double-quotes-yt5/4026/13 "2025-01-10T00:00:28Z")

</div>

Hi @pnicto, I agree that `\n` should be treated as a newline, but the key question is _who_ should handle that interpretation.

In Go, the responsibility might lies with `exec.Command`. Since it directly executes the provided arguments, we need to respect how it expects those arguments to be passed.

Specifically, if exec.Command expects a `backslash` followed by `n` (ASCII: 92 and 110) but receives a `line feed` (ASCII: 10), it could lead to unexpected behavior.

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/3X/7/0/700657133935c15703e22c7c8870394f6e6dc27d.svg) [@system](https://forum.codecrafters.io/u/system)\
**Post date:** [January 15, 2025, 12:01am UTC](https://forum.codecrafters.io/t/shell-backslash-within-double-quotes-yt5/4026/14 "2025-01-15T00:01:14Z")

</div>

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.
