-2

I'm building a shell script (trying to be POSIX compliant) and I'm stuck in an issue. The script is supposed to receive an URL and do some things with it's content.

myscript www.pudim.com.br/?&args=ok

The thing is, the ampersand symbol is interpreted as a command additive, and giving to my script only the www.pudim.com.br/? part as an argument.

I know that the right workaround would be to surround the URL with quotes but, because I need to use this script several times in a row, I wanted to paste the URL's without having to embrace it with quotes every time.

Is there some way to get the full URL argument, somehow bypassing the ampersand?

  • Pass it as "www.pudim.com.br/?&args='ok'" – Prayson W. Daniel Dec 22 '19 at 15:28
  • @PraysonW.Daniel Thank you, but what I'm trying to do is pass the URL as argument without the quotes surrounding it. –  Dec 22 '19 at 15:32
  • Why are you trying to avoid using quotes? How is that "painful"? – larsks Dec 22 '19 at 15:33
  • 1
    @larsks Could you please, instead of questioning my reasons for this being painful, provide some constructive answer? I could have motor issues in my hand for example. That would be literally painful. –  Dec 22 '19 at 15:37
  • 1
    Teodoro, it's obvious you're new here. It was just a friendly question. There's no need to get snarky. The more information we have about your problem the better the answers we can provide. – larsks Dec 22 '19 at 15:44
  • @larsks Misinterpreted your intentios, sorry about that (and you're right, I'm new here). Ok. I'm just trying to avoid wrapping the URL in single quotes every time I run the script, because sometimes the URL will contain an ampersand, sometimes it won't, and I've made mistakes in the past because of the unescaped ampersand. –  Dec 22 '19 at 16:13

2 Answers2

0

You can escape just the ampersand; quotes effectively escape every character between them.

myscript www.pudim.com.br/\?\&args=ok  # The ? should be escaped as well

There is no solution that lets you avoid all quoting, as & is a shell metacharacter whose unquoted meaning cannot be disabled. The & terminates the preceding command, causing it to be run in a background process; adding some redundant whitespace, you attempt is the same as

myscript www.pudim.com.br/? &
args=ok

Unescaped, the ? will cause the URL to be treated as a pattern to expand. However, it's unlikely the pattern will match any existing file, and bash's default behavior is to treat an unmatched pattern literally. (The failglob option will treat it as an error, and the nullglob option will make the URL disappear completely from the command line, but neither option is enabled by default.)

chepner
  • 497,756
  • 71
  • 530
  • 681
  • Hmm ok, I get it. I was trying to get the rest of the URL inside the script, but, as it seems, I can't. –  Dec 22 '19 at 15:39
  • 2
    The reason your script didn't get the full URL is that the `&` causes the command to be treated as two separate commands: `myscript www.pudim.com.br/?` terminated by a `&` (indicating it should run in the background), and `args=ok` as the second. The `&` has to be quoted in some fashion to avoid it being treated as a command terminator. Once you've done that, the entire URL will again be parsed as a single word, and the entire string will be received by your script as a single argument. – chepner Dec 22 '19 at 15:40
  • Strictly speaking, quotes are usually overkill, as they escape every character, even those whose meaning is the same escaped or unescaped. Generally, it's just easier to quote an entire string containing characters in need of escaping than it is to pick and choose which individual characters to escape with a backslash. – chepner Dec 22 '19 at 15:43
  • @chepner Should add this to your answer, since it explains consequences for unescaped arguments having `&` inside. – hc_dev Dec 22 '19 at 15:58
0

Quotes for full URL

Wrapping the URL in quotes will be your only chance. See popular shell utility curl, as it states for its core argument URL:

When using [] or {} sequences when invoked from a command line prompt, you probably have to put the full URL within double quotes to avoid the shell from interfering with it. This also goes for other characters treated special, like for example '&', '?' and '*'.

See also this question and that.

Extra argument(s) for specifying query parameters

You can also pass query parameter (key-value pair) as separate argument. So you can bypass & as separator. See curl's -F option:

-F, --form <name=content>

Read URL from STDIN

If your script allows user interaction you could read the unescaped URL (including metachars as &) from an uninterpreted input-source. See this tutorial.

hc_dev
  • 8,389
  • 1
  • 26
  • 38
  • 1
    A useful __tip dealing with quoted argurment__: first type the command as template with empty quotes, for example `curl ""`. Then move the cursor between the quotes and insert your _unescaped string_ (e.g. the URL). May be you can use some shortcuts like SHIFT + CRTL + V for pasting. – hc_dev Dec 22 '19 at 16:32