[BASH] Programmaufruf ... finde den Fehler nicht
-
#!/bin/bash cmd["1"]="Herunterfahren# sudo halt" cmd["2"]="Neustart# sudo reboot" cmd["3"]="\"Suspend to RAM\"# Xdialog --msgbox \"Not implemented yet\" 10 30 5" cmd["4"]="\"Suspend to Disk\"# Xdialog --msgbox \"Not implemented yet\" 10 30 5" for id in ${!cmd[*]} do title=$(echo ${cmd[$id]} | cut -d'#' -f1) menu="$menu $id $title" done Xdialog --no-tags -menubox$menu
Wenn ich am Ende Xdialog aufrufe, wird ein falsches Menu erzeugt obwohl der Menu-String absolut korrekt ist. Was könnte da schief laufen?
-
Dieser Thread wurde von Moderator/in rüdiger aus dem Forum Rund um die Programmierung in das Forum Linux/Unix verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
trolltäch schrieb:
#!/bin/bash cmd["1"]="Herunterfahren# sudo halt" cmd["2"]="Neustart# sudo reboot" cmd["3"]="\"Suspend to RAM\"# Xdialog --msgbox \"Not implemented yet\" 10 30 5" cmd["4"]="\"Suspend to Disk\"# Xdialog --msgbox \"Not implemented yet\" 10 30 5" for id in ${!cmd[*]} do title=$(echo ${cmd[$id]} | cut -d'#' -f1) menu="$menu $id $title" done Xdialog --no-tags -menubox$menu
Wenn ich am Ende Xdialog aufrufe, wird ein falsches Menu erzeugt obwohl der Menu-String absolut korrekt ist. Was könnte da schief laufen?
cmd["1"]= finde ich seltsam, denn cmd[1]= kommt aufs selbe raus. Bei Initialisierungen gibt es aber eine noch elegantere Syntax: array=( a b c ).
Anstelle mit "" zu quoten und dann innen drin \" zu schreiben kannst du auch direkt mit '' quoten.
${!cmd[]} ist wackelig, falls du mal aus irgendeinem Grund andere Keys verwenden solltest. Im Zweifelsfall würde ich immer [@] nehmen statt [], außer es gibt sehr gute Gründe, die für [*] sprechen.
Ich hab hier leider kein Xdialog, aber die manpage zu Xdialog sagt:
--menubox <text> <height> <width> <menu height> <tag1> <item1> {<help1>}...Dein Format ist also schonmal nicht korrekt. $menu ungequotet übergeben ist sowieso sehr riskant, denn da verlässt du dich darauf dass schon alles irgendwie passen wird. Hier passt es aber nicht, weil du Einträge mit Leerzeichen hast.
Die Lösung wär also auch hier ein Array zu verwenden und dann am Ende Xdialog die Parameter mit "${menu[@]}" zu übergeben. Wichtig sind hier zwei Dinge
1. "" drumherum
2. [@] statt [*]Das manuelle Simulieren eines Arrays mit # als Trenner kommt mir auch unnötig umständlich vor.
Das könnte zum Beispiel so aussehen:
#!/bin/bash cmd=( 'Herunterfahren' 'sudo halt' 'Neustart' 'sudo reboot' 'Suspend to RAM' 'Xdialog --msgbox "Not implemented yet" 10 30 5' 'Suspend to Disk' 'Xdialog --msgbox "Not implemented yet" 10 30 5' ) menu=( ) for (( i=0; i<${#cmd[@]}; i+=2 )) do menu[$i]=$(( i + 1 )) menu[$(( i + 1 ))]=${cmd[$i]} done # Nur zu Debug-Zwecken print_all_params() { for c in "$@"; do printf '[%s]\n' "$c" done } print_all_params "${menu[@]}"
Ausgabe sollte sein:
[1] [Herunterfahren] [3] [Neustart] [5] [Suspend to RAM] [7] [Suspend to Disk]
Das ist so zu deuten, dass
print_all_params "${menu[@]}"
expandiert zu
print_all_params 1 Herunterfahren 3 Neustart 5 'Suspend to RAM' 7 'Suspend to Disk'
mit richtigem Quoting und allem.
Die Zahlen sind genau die Array-Indizes, mit denen du später an die command line kommen kannst.