0

When I try to run the code below, the shell is replacing (because they are not defined as a bash variable) $4 and $2 with blanks. My question is, how do I keep bash from trying to evaluate the positional parameters for awk as its variables? I've tried putting double and single quotes around the positional parameters, however, that did not suppress bash from interpreting them as local variables instead of strings.

This is what is returned when I echo "$x$i$y"

date -r /root/capture/capture11.mp4 | awk '{print }' | awk -F":" '/1/ {print }'

Code:

#!/bin/sh
i=$(cat /etc/hour.conf)
x="date -r /root/capture/capture"
y=".mp4 | awk '{print $4}' | awk -F\":\" '/1/ {print $2}'"
$x$i$y

Any help would be greatly appreciated!

anubhava
  • 761,203
  • 64
  • 569
  • 643
user3308131
  • 159
  • 1
  • 5
  • 16

3 Answers3

3

Variables are interpolated inside double quotes. Use single quotes, or escape them like \$2.

However, the way you're trying to split up the command into separate variables won't work. Instead, you should use a function. Then you don't need to deal with quotes and escaping at all. For instance:

do_thing() {
    date -r "/root/capture/capture$1.mp4" | awk '{print $4}' | awk -F':' '/1/ {print $2}'
}

do_thing "$(cat /etc/hour.conf)"
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • Thanks for your example. I'm a newbie (as if you couldn't tell) to bash shell scripting. In your example how are the results returned ? calling it with an assignment ? time=do_thing "$(cat /etc/hour.conf)" – user3308131 Jun 17 '17 at 13:27
  • Functions work just like regular commands. `do_thing "$(cat /etc/hour.conf)"` will print its output to stdout. If you want to capture the output, do `time=$(do_thing "$(cat /etc/hour.conf)")`. If you want to pipe it to another command, do `do_thing "$(cat /etc/hour.conf)" | awk | sed | grep`. – John Kugelman Jun 17 '17 at 13:34
  • Thanks! I appreciate the help! – user3308131 Jun 17 '17 at 13:37
  • And you don't even need the function for that, just doing `date -r "/blah${i}.mp4" | awk '...'` would be fine – ilkkachu Jun 17 '17 at 13:57
0

$4 is doubled quoted. Though there are single quotes, it is included in double quotes. So the single quotes are just part of the string and it won't keep the literal meaning of $. So you can escape the $:

y=".mp4 | awk '{print \$4}' | awk -F\":\" '/1/ {print \$2}'"

Or, use single quotes around the whole part:

y='.mp4 | awk "{print \$4}" | awk -F':' "/1/ {print \$2}"'
zhenguoli
  • 2,268
  • 1
  • 14
  • 31
0

Concatenating variables like that to build a command line sort of works, but quotes within the variables don't quote anything, they'll just be taken as literal quotes.

This sort of works (but is horrible):

$ x=prin; y="tf %f\\n"; z=" 123456789"
$ $x$y$z
123456789.000000

This doesn't do what you want:

$ z='"foo bar"'; printf $y ; echo
"foo

Instead of one argument foo bar, printf gets the two arguments "foo and bar".

ilkkachu
  • 6,221
  • 16
  • 30