J V
J V

Reputation: 11936

Inserting variables as command arguments in a bash script

I have a file for screencasting on linux, and I want to modify parts of it based on user input. At the moment I can't even get it to stick an argument in a command from a variable.

#!/bin/bash -x

fps="30"
capturesize="hd1080"
outputsize="720"

filter=-vf 'scale=${outputsize}'

avconv \
-f x11grab -r $fps -s $capturesize -i :0.0 \
-f alsa -ac 2 -i pulse \
-f alsa -ac 2 -i pulse \
-f alsa -ac 1 -i pulse \
-map 0:0 -map 1:0 -map 2:0 -map 3:0 \
-vcodec libx264 \
$filter \
-pre:v lossless_ultrafast \
-acodec libmp3lame \
-threads 4 \
-y $@

$fps and $capturesize are evaluated properly but $filter assignment gives a nice little:

+ filter=-vf
+ 'scale=${outputsize}'
~/bin/screencap: line 9: scale=${outputsize}: command not found

Changing the line to:

filter="-vf 'scale=$outputsize'"

Gives an even less pleasant:

+ filter='-vf '\''scale=720'\'''
+ avconv -f x11grab [...] -vf ''\''scale=720'\''' [...]
[...]
No such filter: 'scale=720'
Error opening filters!

Upvotes: 0

Views: 307

Answers (2)

chepner
chepner

Reputation: 530920

Use an array. It has the added benefit of protecting items that contain spaces, something you can't do if you try to store it in a space-separated list.

#!/bin/bash -x

fps="30"
capturesize="hd1080"
outputsize="720"

filter=( -vf "scale=${outputsize}" )

avconv \
-f x11grab -r "$fps" -s "$capturesize" -i :0.0 \
-f alsa -ac 2 -i pulse \
-f alsa -ac 2 -i pulse \
-f alsa -ac 1 -i pulse \
-map 0:0 -map 1:0 -map 2:0 -map 3:0 \
-vcodec libx264 \
"${filter[@]}" \
-pre:v lossless_ultrafast \
-acodec libmp3lame \
-threads 4 \
-y "$@"

You can put all the options in a single array; a small example:

options=( -f x11grab -r "$fps" -s "$capturesize" )
options+=( -i :0.o )
# etc
avconv "${options[@]}" -y "$@"

Upvotes: 2

michaelmeyer
michaelmeyer

Reputation: 8205

filter="-vf scale=${outputsize}"

Upvotes: 0

Related Questions