1

EDIT: Question was marked as a duplicate, please observe that value is sent in a specific way with double quotes like "--parameter value" "--parameter2 value2" this question has not been asked and does not have an answer.

Problem

If the parameters are given double quoted like "--parameter value" "--parameter2 value2", how can I pass them so that an end script can take it as --parameter value --parameter2 value?

If I try $@ (without double quotes) it only works if parameter values do not contain whitespaces. If I try "$@" it does not work at all. Please see the scenario below that explains the problem with three files.

Real life scenario

  1. GitHub action (action.yml) calls a Dockerfile with double quoted parameter name and value pairs "--parameter value" "--parameter2 value2"
  2. Dockerfile in its entry point calls a shell script expecting parameters as --parameter value --parameter2 value2 (without double quotes per parameter name / value pair).

Simplified scenario

There are three steps in the call flow: the caller.sh, middleman.sh and script.sh. And I'm only in control of the middleman.

enter image description here

Caller

The entrypoint script. It calls the middleman in specific way where each parameter name and value is double quoted together. I cannot control the behavior of this script.

So we could represent it with caller.sh that would look like this:

#!/usr/bin/env bash

./middleman.sh "--parameter1 value" "--parameter2 'value with whitespace'"

Middleman

This is the middle layer that's supposed to take the parameters from the caller and translates them into expanded parameters as the script would expect.

middleman.sh:

#!/usr/bin/env bash

./script.sh "$@"

This is where the problem lies as this does not work. I tried also with $@ without double quotes but then it only works if parameter values contain white space. How can I have the right call here?

Script

The script that's supposed to take the parameters in a right way. It wants to receive parameters such as --name value.

It works by parsing the parameters as following and e.g. prints them:

script.sh:

#!/usr/bin/env bash

while [[ "$#" -gt 0 ]]; do case $1 in
  --parameter1) FIRST_PARAM="$2"; shift;;
  --parameter2) SECOND_PARAM="$2"; shift;;
  *) echo "[script.sh] Unknown parameter passed: '$1'"; exit 1;;
esac; shift; done

echo "[script.sh] parameter1: $FIRST_PARAM, second parameter: $SECOND_PARAM"

I cannot modify this script.

Run the test

./caller.sh

U. Bulle
  • 1,075
  • 9
  • 20

1 Answers1

1

how can I pass them so that an end script can take it as --parameter value --parameter2 value?

Pass it normally:

./middleman.sh --parameter1 value --parameter2 'value with whitespace'

How can I have the right call here?

The presented code is correct, just:

./script.sh "$@"

For more information research word splitting expansion and quoting in shell. It's not how you pass arguments, it's how you "forward" and "parse" them - and "$@" is the correct way.

Side note: case is special - the $1 in case $1 in does not undergo word splitting, so there is no need to quote it. I like quote all expansions and would write case "$1" in anyway.

Check your scripts with shellcheck.net .

Aaaand tested on repl.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • Hi, thanks a lot! But I cannot change the behavior of `caller.sh`, it's static and it unfortunately always calls parameter name and value pairs in quotes. I updated the question with real life scenario. So how can I "normalize" those quoted parameters? Btw my question is closed because of duplicate. This problem has never been stated before... – U. Bulle Jan 11 '21 at 15:31
  • ? You do not control github actions? `how can I "normalize" those quoted parameters?` Write a parser. Now you changed the quoting also. So write a parser - extract the string before first space and after first space, create from these two strings two arguments and pass them along – KamilCuk Jan 11 '21 at 15:40
  • 1
    Thanks. A simple solution like parsing I could not come up with sticking with `$@`. And sorry for not being clear enough about the quotes. I'm using `action.yml` (own action) and it always call the Dockerfile using its `args` by quoting key / value parameter pairs.I came up with this solution to support both normal parameter input and double quoted it works fine: https://gist.githubusercontent.com/undergroundwires/b384e499fd8ba850df173b685b30e32c/raw/08fe82da0109c5c1a36e8eea68a5e122fe9f4b7a/middleman.sh . I'd appreciate feedback otherwise feel free to update your answer and I'll accept it. – U. Bulle Jan 12 '21 at 07:41
  • `I'd appreciate feedback` Nice script ;) I would merge it. – KamilCuk Jan 12 '21 at 07:51