-4

This is most likely a stupid mistake I made somewhere but I just cannot seem to figure out what's happening. Hoping I can find some help here.

I have a script callee.sh that expects some optional variable $1,$2,$3 etc... and it does a bunch of echo in the script (so, multiple lines of output) I only want to last line as the result. The other lines are just debug status reports.

When try to assign the result to a variable like this

result=`./callee.sh | tail -n 1` It works perfectly

However, if it takes parameter

result=`./callee.sh param1 param2 param2 | tail -n 1` The code would block for ever, never entering callee.sh

Just for comparsion I tried running

result=`./callee.sh`, This works but all the lines are append to one line (that's fine)

but running

result=`./callee.sh param1 param2 param2` also hangs for ever. Never entering callee.sh

What did I do wrong? What should I do instead?

user1763590
  • 117
  • 2
  • 14
  • 2
    How much time does the command `./callee.sh param1 param2 param2` (without backticks) take to run? – Leon Jul 18 '16 at 18:53
  • thanks for pointing out the typo. Fixed – user1763590 Jul 18 '16 at 18:53
  • 6
    If `./callee.sh` runs to completion but `./callee.sh param1 param2 param2` hangs forever, then your problem is inside `callee.sh`. – John1024 Jul 18 '16 at 18:54
  • 4
    Please [edit] your question to include a [mcve] (basically add the contents of `callee.sh`). Without it only guesses can be made at the problem. – Jonny Henly Jul 18 '16 at 18:55
  • 3
    `result` will still contain the newlines from the output; if you are seeing one line, it's because you aren't quoting the parameter expansion properly. (Compare `echo $result` with `echo "$result"`.) – chepner Jul 18 '16 at 18:57

2 Answers2

0

Don't know without the code, but the short answer is to use

result=$(./callee.sh ...)

instead of backticks. $(...) properly handles nested parentheses.

Also, use / instead of \.

And, as @Leon pointed out, use tail -1 or tail -n 1, not tail -n -1.

cxw
  • 16,685
  • 2
  • 45
  • 81
  • ```result=$(./callee.sh param1 param2 param3)``` Also hangs for ever. Never entering ```./callee.sh``` The problem I am having seems to not have anything to do with nested backticks though – user1763590 Jul 18 '16 at 18:54
  • 1
    That's mainly a style suggestion; although a very good one, it will not solve the OP's problem. – chepner Jul 18 '16 at 18:56
  • 2
    @user1763590 How do you know it isn't entering `callee.sh` as opposed to hanging within `callee.sh`? Please trim `callee.sh` and the calling code down to the smallest example that still shows the problem and then [edit your question](http://stackoverflow.com/posts/38443957/edit) to include the code of that example, both the calling script and `callee.sh`. Thank you! – cxw Jul 18 '16 at 18:58
  • 1
    @chepner Generally so, but since the OP didn't actually show the contents of `param1` &c., there was a chance they might include character sequences that interacted unexpectedly with backtick expansion. I figured that was worth a shot :) . – cxw Jul 18 '16 at 18:59
  • 1
    The backticks are parsed before anything inside them is expanded. – chepner Jul 18 '16 at 19:01
  • 1
    @cxw That backtick is just another literal character in the value of `param1`. It does not affect the command substitution at all. `foo='foo\`bar'; echo \`echo $foo\``. – chepner Jul 18 '16 at 19:07
  • replacing backtick with ```$(...)``` does not seem to work for me either. Not sure whether showing the script helps as ```callee.sh``` was never entered. This seem to be a syntax issue other than script specific. – user1763590 Jul 18 '16 at 19:32
  • @user1763590 I'm very sorry, but I really can't help you without more code. As others have requested, please add the smallest code that shows the problem. Maybe try using temp files instead: `./callee.sh param1 param2 param2 > test1.txt ; tail -n 1 test1.txt > test2.txt; ` and see where your problems are. Remember that *debug output is not always reliable* in the presence of pipes. If you are waiting for an `echo` to present output, it might be going into what the `tail` is discarding. I'd like to help but need more from you in order to do so! – cxw Jul 18 '16 at 19:51
  • @user1763590 If it were a syntax error, you would most likely get a message from `bash` to that effect, followed by termination of the script. If something is hanging, it probably means `bash` was able to parse and run whatever isn't terminating. **Another option**: run the commands of your script one at a time by hand. **Still another:** put `set -x` at the top of the caller script and `callee.sh` to see what `bash` thinks is going on. – cxw Jul 18 '16 at 19:53
-1

if the call to callee.sh is hanging with parameters, try executing it outside the script with parameters and check if it is hanging there as well... Anyways, the best way of saving output (and printing it out afterwards):

result="$(./callee.sh param1 param2 param2)"
echo "${result}" <--- this should show the line breaks
Sebastian Breit
  • 6,137
  • 1
  • 35
  • 53
  • yeah, it hangs when I call the script like this as well. When I said hang I mean the script is never entered. The reason I tried to ```tail``` inline is because otherwise the multi line output would be appended into 1 line and ``tail``` would return the whole thing which is not what I need. But that's beside the point. Even without ```tail``` the script is never called either. – user1763590 Jul 18 '16 at 19:16