9

I have syntax error near unexpected token & in next : in bash scripts its'go like this :

#!/bin/bash
var1=`(/usr/bin/time cdifonline -CD 186821 -ALL > /dev/null)|& grep real|awk '{print $2}'`

when i issue this command on cli i get good output, problem is when invoke this in script i can get any output from var1

./check_cdifonline.sh: command substitution: line 2: syntax error near unexpected token `&'
./check_cdifonline.sh: command substitution: line 2: `(/usr/bin/time cdifonline -CD 186821 -ALL >/dev/null) | & grep real | awk '{print $2}''
3
  • Why are you &ing the grep? You're already piping the output to grep. Commented Dec 12, 2013 at 20:52
  • Because i need to parse real value from time command and you need to send to stderr first to get output from time, it's not possible Commented Dec 12, 2013 at 21:05
  • Your question has been edited to fix the formatting, but there are still a few dangling characters at the end of the first code block. You can fix that by editing your question, deleting the first code block and replacing it by a copy-and-paste of your actual code, then selecting the block and clicking the {} to format it as code (which just indents it 4 columns). Commented Dec 12, 2013 at 21:16

3 Answers 3

15

You can use the sequence |& to pipe both stdout and stderr from one process to another.

You cannot have a space between the | and the &. (csh and tcsh allow a space; bash does not.) I suspect you happen to be typing it without the space when you run the command interactively; the syntax is the same either way.

This:

foo |& bar

is shorthand for this:

foo 2>&1 | bar

UPDATE :

With bash 3.2.25, the |& token is not recognized; was added as a new feature in bash 4.1. Running your script with the older bash, I get the same error message you do.

To make your script compatible with older versions of bash, just do the equivalent redirection without using the |& operator:

#!/bin/bash
var1=`(/usr/bin/time cdifonline -CD 186821 -ALL > /dev/null) 2>&1 | grep real | awk '{print $2}'`

Further refinements: Use $(...) rather than `...`:

#!/bin/bash
var1=$((/usr/bin/time cdifonline -CD 186821 -ALL > /dev/null) 2>&1 | grep real | awk '{print $2}')

You can also incorporate the grep search into the awk command:

#!/bin/bash
var1=$((/usr/bin/time cdifonline -CD 186821 -ALL > /dev/null) 2>&1 | awk '/real/ {print $2}')

Warning: I have not thoroughly tested these beyond verifying that they run without syntax errors.

I still see no difference between |& and | &. Is it possible that /bin/bash is a different version than what you're running interactively? Try /bin/bash --version and echo $BASH_VERSION.

Sign up to request clarification or add additional context in comments.

6 Comments

i have same problem without spacing, command works just fine in cli and it's realy anoying
I just copy-and-pasted the code from your question and ran it on my own system. There was no error. (I don't have the cdifonline command, but that shouldn't affect any syntax errors.) I do get an error if I invoke it as sh ./foo.bash; how exactly are you running the script? Try copy-and-pasting the script from your question into a new file and running that.
no it's helples, as i sad everything is just fine on cli but when invoke in script i get this error
Did you try what I suggested? What version of bash are you using (bash --version)?
bash --version GNU bash, version 3.00.0(2)-release (sparc-sun-solaris2.6) Copyright (C) 2004 Free Software Foundation, Inc.
|
0

Try change to:

var1=$(/usr/bin/time cdifonline -CD 186821 -ALL >/dev/null | awk '/real/ {print $2}')

4 Comments

(/usr/bin/time cdifonline -CD 186821 -ALL > /dev/null | awk '/real/ {print $2}') Ambiguous output redirect.
Does this alone give an output? /usr/bin/time cdifonline -CD 186821 -ALL >/dev/null and if so, what?
/usr/bin/time cdifonline -CD 186821 -ALL >/dev/null real 3.2 user 0.4 sys 0.1
(/usr/bin/time cdifonline -CD 186821 -ALL > /dev/null)|& grep real|awk '{print $2}' 1.3 when issue on cli i get what i want i just need this in bash script to set as variable
0

Thanks Keith I have no problems anymore you saved my day :) so the bash version was the problem and with avoiding of & I have no errors, thanks also for fine tuning :)

so this works with my bash version

#!/bin/bash
var1=`(/usr/bin/time cdifonline -CD 186821 -ALL > /dev/null) 2>&1 | grep real | awk '{print $2}'`

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.