使用 kdialog bash 脚本创建动态选项菜单:Printf 无法完成这项工作?引用问题

发布于 2024-12-20 12:00:00 字数 1386 浏览 3 评论 0原文

我想用 kdialog 创建一个菜单,就像

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

现在

数组 a 包含选项 数组 b 包含配置文件的名称,

似乎 kdialog 对“-ab”有一些问题,通常它似乎需要 -stuff 之类的选项,因此它需要是“\”-vcodec mpeg2\“”。

基本上我的问题是一个引用问题,我使用了 printf 但我无法得到它,

这是我的代码:

a=(-vcodec mp3 -ab 128k, -vcodec mpeg2video -b 1200k -ab 128k -acodec mp3 -r 25 -ar 44100 ) ; b=(mp3, mpg) ; eval kdialog --menu "选择您的个人资料" $(for ((i = 0; i <=$(( ${#a[@]} -1 )) ; i++ )) ; do printf "\\'% s\\' %s " "${a[i]}" "${b[i]}" ;完成)

解决方案

文件来读取

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

我执行的 $HOME/FFmpeg_profiles.lst 脚本

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

野味少女 2024-12-27 12:00:00
#!/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

我们使用 xargs 来克服引用选项(带空格)被视为多个参数而不是单个参数的问题,即“kdialog $ARGS”将不起作用正如预期的那样。

xargs 优于“eval kdialog $ARGS”,因为它可以避免命令注入。


更新

根据您实际从文本文件加载值的更新示例,您可以在没有中间数组的情况下执行相同的操作:

#!/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
#!/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
狼亦尘 2024-12-27 12:00:00

添加 -- 来指示选项处理结束,如下所示:

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

问候

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

醉生梦死 2024-12-27 12:00:00

这可能对您有用:

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

这仅使用一个数组 a,如果您有两个数组(ab),只需将它们合并为第三个,像这样:

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

编辑:

原始问题已被修改,这是一个可能有效的新解决方案:

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. FFmpeg_profile.lst 文件构建 kdialog 命令。
  2. 每个选项和菜单标签都位于单独的行上,因此请使用 paste 来旋转它们。
  3. 通过 shell 通过管道传输 kdialog 命令并将插值结果保存在变量中。

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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文