Create dynamic options menu with kdialog bash script : Printf can't do the job ? quoting issue

StackOverflow https://stackoverflow.com/questions/8443515

  •  12-03-2021
  •  | 
  •  

Pergunta

i would like create a menu with kdialog like this

  kdialog --menu "choose your profile"  "\"-vcodec mpeg2\"" "mpeg" 
  "\"vcodec stuff -ab 100ak\"" "avi" "\"-acodec mp3 -ab 128k"\" "mp3"

now

array a contains options array b contains name of a profile

it seems kdialog has some problem with "-ab" generally it seemes it takes -stuff like an option so it needs to be "\"-vcodec mpeg2\"".

basically my problem is a quoting problem , i have used printf but i can't get it

this is my code:

a=(-vcodec mp3 -ab 128k, -vcodec mpeg2video -b 1200k -ab 128k -acodec mp3 -r 25 -ar 44100 ) ; b=(mp3, mpg) ; eval kdialog --menu "choose your profile" $(for ((i = 0; i <=$(( ${#a[@]} -1 )) ; i++ )) ; do printf "\\'%s\\' %s " "${a[i]}" "${b[i]}" ; done)

solution

file to read $HOME/FFmpeg_profiles.lst

mpeg  -vcodec mpeg2 -ab 1000k 
avi  -vcodec avi -ab 1000k   
mp3 -acodec mp3 -ab 128k

script i did

function_load_profiles(){
k=0
while read line; do 

nameprofile[$k]="$(echo "$line" | awk '{print $1}')"
ffmpegoptionprofile[$k]="$(echo "$line" | awk '{ for(b=2; b<=NF; b++) {printf("%s ", $b)} } ' )"


 k=$(( $k+1 ))
done < "$HOME/FFmpeg_profiles.lst"

}

function_load_profiles 

ARGS="--menu \"choose your profile\" --"
for ((i=0; i<${#nameprofile[@]}; i++)); do
    ARGS="$ARGS \"${ffmpegoptionprofile[$i]}\" \"${nameprofile[$i]}\""
done

SELECTED_OPTIONS=$(echo $ARGS | xargs kdialog)
echo $SELECTED_OPTIONS
Foi útil?

Solução

#!/bin/bash
A=("-vcodec mp3 -ab 128k"  
   "-vcodec mpeg2video -b 1200k -ab 128k -acodec mp3 -r 25 -ar 44100")
B=("mp3" "mpg")

# Build command line args
ARGS="--menu \"choose your profile\" --"
for ((i=0; i<${#A[@]}; i++)); do
    ARGS="$ARGS \"${A[$i]}\" \"${B[$i]}\""
done

SELECTED_OPTIONS=$(echo $ARGS | xargs kdialog)
echo $SELECTED_OPTIONS

We use xargs to overcome the issue of the quoted options (with spaces) being treated as multiple args instead of a single argument, i.e. "kdialog $ARGS" won't work as expected.

xargs is preferable to "eval kdialog $ARGS" as it can avoid command injection.


Updates

Based on your updated example where you're actually loading the values form a text file, you can do the same without the intermediate arrays:

#!/bin/bash
PROFILE_FILE="FFmpeg_profiles.lst"
ARGS="--menu \"choose your profile\" --"

while read PROFILE OPTS; do
    ARGS="${ARGS} \"${OPTS}\" \"${PROFILE}\""
done < $PROFILE_FILE

echo $ARGS | xargs kdialog

Outras dicas

put a -- to indicate end of option processing, like this:

kdialog --menu "choose your profile" -- "-vcodec mpeg2" "mpeg" "vcodec stuff -ab 100ak" "avi" "-acodec mp3 -ab 128k" "mp3"

Regards

This might work for you:

a=("-vcodec mpeg2" "mpeg" "vcodec stuff -ab 100ak" "avi" "-acodec mp3 -ab 128k" "mp3")
kdialog --menu "Choose your profile:" $(printf ' "%s" %s' "${a[@]}")

This uses just one array a, if you have two (a and b) just merge them into a third, like so:

a=(a b c) b=(1 2 3) j=0
for i in ${!a[@]}; do c[j++]="${a[i]}"; c[j++]="${b[i]}" ;done
echo "${c[1]}"
1

EDIT:

Original question has been modified, here's a new solution that might work:

options=$(sed -e '1i\echo kdialog --menu "Choose your profile:"'\
              -e 's/\s*\(\w*\)\s*\(.*\S\)\s*/"\2" \1/' $HOME/FFmpeg_profile.lst |\
        paste -sd' ' | sh)
  1. Build the kdialog command from the FFmpeg_profile.lst file.
  2. Each option and menu tag are on separate lines, so use paste to pivot them.
  3. Pipe the kdialog command through the shell and save the interpolated result in a variable.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top