Error in script

While installing kubernetes, I have to run 1 script. Below is a part of that code. I am getting an error as

-bash: syntax error near unexpected token `}'

Please help me to find what changes are required for the below mentioned piece of code.

kube::util::godep_restored() {
  local -r godeps_json=${1:-Godeps/Godeps.json}
  local -r gopath=${2:-${GOPATH%:*}}
  if ! which jq &>/dev/null; then
    echo "jq not found. Please install." 1>&2
    return 1
  fi
  local root
  local old_rev=""
  while read path rev 
do
    rev=$(echo "${rev}" | sed "s/['\"]//g") # remove quotes which are around revs sometimes

    if [[ "${rev}" == "${old_rev}" ]] && [[ "${path}" == "${root}"* ]]; then
      # avoid checking the same git/hg root again
      continue
    fi

    root="${path}"
    while [ "${root}" != "." -a ! -d "${gopath}/src/${root}/.git" -a ! -d "${gopath}/src/${root}/.hg" ] 
	do
      root=$(dirname "${root}")
    done
    if [ "${root}" == "." ]; then
      echo "No checkout of ${path} found in GOPATH \"${gopath}\"." 1>&2
      return 1
    fi
    local head
    if [ -d "${gopath}/src/${root}/.git" ]; then
      head="$(cd "${gopath}/src/${root}" && git rev-parse HEAD)"
    else
      head="$(cd "${gopath}/src/${root}" && hg parent --template '{node}')"
    fi
    if [ "${head}" != "${rev}" ]; then
      echo "Unexpected HEAD '${head}' at ${gopath}/src/${root}, expected '${rev}'." 1>&2
      return 1
    fi
    old_rev="${rev}"
  done<(jq '.Deps|.[]|.ImportPath + " " + .Rev' -r < "${godeps_json}")
  return 0
}

On the two but last line:

done<( ....

try:

done < <( ...

I tried with the suggested option, but it's still not working. I am getting below error :

syntax error near unexpected token `<'

Code snippet :

{
  local -r godeps_json=${1:-Godeps/Godeps.json}
  local -r gopath=${2:-${GOPATH%:*}}
  if ! which jq &>/dev/null; then
    echo "jq not found. Please install." 1>&2
    return 1
  fi
  local root
  local old_rev=""
  while read path rev 
do
    rev=$(echo "${rev}" | sed "s/['\"]//g") # remove quotes which are around revs sometimes

    if [[ "${rev}" == "${old_rev}" ]] && [[ "${path}" == "${root}"* ]]; then
      # avoid checking the same git/hg root again
      continue
    fi

    root="${path}"
    while [ "${root}" != "." -a ! -d "${gopath}/src/${root}/.git" -a ! -d "${gopath}/src/${root}/.hg" ] 
do
      root=$(dirname "${root}")
    done
    if [ "${root}" == "." ]; then
      echo "No checkout of ${path} found in GOPATH \"${gopath}\"." 1>&2
      return 1
    fi
    local head
    if [ -d "${gopath}/src/${root}/.git" ]; then
      head="$(cd "${gopath}/src/${root}" && git rev-parse HEAD)"
    else
      head="$(cd "${gopath}/src/${root}" && hg parent --template '{node}')"
    fi
    if [ "${head}" != "${rev}" ]; then
      echo "Unexpected HEAD '${head}' at ${gopath}/src/${root}, expected '${rev}'." 1>&2
      return 1
    fi
    old_rev="${rev}"
  done < <(jq '.Deps|.[]|.ImportPath + " " + .Rev' -r < "${godeps_json}")
  return 0
}

What's your shell version? "process substitution" works only in recent shells.

$ echo $BASH_VERSION
4.4.12(3)-release

I am running this script through CYGWIN as I could not find any other option to run shell script in windows machine. Please let me know if I need to download the latest version or any other tool to run this script.

What does your bash 's man page say about "process substitution"?

Can you please help me with the command and what to look for exactly?

My man bash says

so it provides that feature.

I can see following output as result of man bash for process substitution :

Process Substitution
Process substitution allows a process's input or output to be referred to using a filename. It takes the form of <(list) or >(list). The process list is run asyn
chronously, and its input or output appears as a filename. This filename is passed as an argument to the current command as the result of the expansion. If the
>(list) form is used, writing to the file will provide input for list. If the <(list) form is used, the file passed as an argument should be read to obtain the output
of list. Process substitution is supported on systems that support named pipes (FIFOs) or the /dev/fd method of naming open files.

   When available, process substitution is performed simultaneously with parameter and variable expansion, command substitution, and arithmetic expansion.
local -r gopath=${2:-${GOPATH%:*}} 

See the red } -- That may be your problem - see line #2

@jim: but the red curly brace (the second closing brace) should be there, no?
It is present in the code in both post #1 and post #3 ...

I don't feel like there is an problem with closing braces as mentioned in above comment. I think there is a problem with jason process substitution which I am not able to figure out.

Here may be your problem:

but you're

  • I'm not sure windows provides either of the required methods in a way that allows process substitution to work.
    Alternative paths: run your jq program and redirect its output to a file which then can be read by your while loop, or pipe jq into the loop.

For below code snippet, Can you please let me know -how to redirect jq program and use it in while loop?

while read path rev 
do
    rev=$(echo "${rev}" | sed "s/['\"]//g") # remove quotes which are around revs sometimes

    if [[ "${rev}" == "${old_rev}" ]] && [[ "${path}" == "${root}"* ]]; then
      # avoid checking the same git/hg root again
      continue
    fi

    root="${path}"
    while [ "${root}" != "." -a ! -d "${gopath}/src/${root}/.git" -a ! -d "${gopath}/src/${root}/.hg" ] 
do
      root=$(dirname "${root}")
    done
    if [ "${root}" == "." ]; then
      echo "No checkout of ${path} found in GOPATH \"${gopath}\"." 1>&2
      return 1
    fi
    local head
    if [ -d "${gopath}/src/${root}/.git" ]; then
      head="$(cd "${gopath}/src/${root}" && git rev-parse HEAD)"
    else
      head="$(cd "${gopath}/src/${root}" && hg parent --template '{node}')"
    fi
    if [ "${head}" != "${rev}" ]; then
      echo "Unexpected HEAD '${head}' at ${gopath}/src/${root}, expected '${rev}'." 1>&2
      return 1
    fi
    old_rev="${rev}"
  done < <(jq '.Deps|.[]|.ImportPath + " " + .Rev' -r < "${godeps_json}")

Assuming that your jq command writes the data you want to read in your while loop onto its standard output, the standard way of doing it would be:

jq '.Deps|.[]|.ImportPath + " " + .Rev' -r < "${godeps_json}" |
    while read path rev 
do
        ... ... ...
done

didn't realise I wasn't looking at the last message in the tread.

Thank you.