0

I am trying to run a .sh file by passing few arguments. The file contains the following.

# escape special characters
ESCAPED_REPLACE=$(printf '%s ' "$@" | sed -e 's/[$()"]/\\&/g')

echo "After replace"
echo $ESCAPED_REPLACE

npx codeceptjs "$ESCAPED_REPLACE" --plugins allure

Following is a sample list of arguments. As it shows the last argument contains double quotes. Which I need to preserve here

./test.sh run --steps --grep "Verifying login"

The issue is once I print the ESCAPED_REPLACE the quotes are lost. Does anyone know why?

Kavin404
  • 959
  • 2
  • 11
  • 18
  • 2
    Just use it as `npx codeceptjs "$@" --plugins allure` – anubhava May 24 '21 at 10:31
  • Note: `$ESCAPSED_REPLACE` contains a typo – Wiktor Stribiżew May 24 '21 at 10:31
  • Please paste your script at [shellcheck.net](http://www.shellcheck.net/) and try to implement the recommendations made there. – Cyrus May 24 '21 at 10:32
  • I want to escape the $ and the brackets passing directly won't work if the argument inside the quotes contains any special character – Kavin404 May 24 '21 at 10:32
  • I need to escape special characters in the argument list before passing it to the npx command. Is there a way I can preserve the quotes – Kavin404 May 24 '21 at 10:36
  • Does it work when you do `./test.sh run --steps --grep '"Verifying login"'`? – mattb May 24 '21 at 11:05
  • `print the ESCAPED_REPLACE the quotes are lost` They are not there in the first place. You have to add the quotes if you want them, like `--grep "\"Verifying login\""` for example, or like above. But adding quotes does _not_ mean it's going to be one word, it's going to be two separate words after word splitting. Anyway, re-read an introduction to shell, research quoting, bash arrays and word splitting expansion in shell. – KamilCuk May 24 '21 at 11:22
  • 1
    Does my answer to [this question](https://stackoverflow.com/questions/10835933/preserve-quotes-in-bash-arguments/10836225#10836225) help clarify what's going on? – Gordon Davisson May 24 '21 at 15:27
  • @Kavin404, if your question is about the proper variable escaping then maybe you should use `printf '%q ' "$@"` instead of your `sed` trick. – andras.tim May 24 '21 at 20:41

2 Answers2

2

Quotes that are passed to your script are printed correctly. However, in your example ./test.sh run --steps --grep "Verifying login" you don't pass any quotes to the script, since bash interprets them before test.sh even runs.

To pass quotes to your script, you have to escape them:

./test.sh run --steps --grep "\"Verifying login\""

Anyways, I'm not sure you really need sed -e 's/[$()"]/\\&/g'. To me this seems like a misunderstanding of how bash interprets special symbols. When you write "$variable" the special symbols inside variable are not interpreted. Therefore, you normally don't have to quote the content of variable. I'd assume the following to work:

Content of test.sh

#! /bin/sh
npx codeceptjs "$@" --plugins allure

Execution

./test.sh run --steps --grep "Verifying login"
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Socowi
  • 25,550
  • 3
  • 32
  • 54
0

Can you do something like:

#!/bin/bash
# file name: test

echo "K: ${@@K}"

echo "find ${@@K}"
eval "find ${@@K}"

This should pass everything to find just as if you typed it directly

$ ./test ../Downloads -name "This is a test.pdf"
K: '../Downloads' '-name' 'This is a test.pdf'
find '../Downloads' '-name' 'This is a test.pdf'
../Downloads/This is a test.pdf

If I am reading your question right, that is what you are trying to do. Special characters will be interpreted in the shell before passing them to your script unless you escape them first:

$ ./test \$var1 "\$var2 \$var3" '$var4 single quotes work too'

Wayne Vosberg
  • 1,023
  • 5
  • 7