• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

[gelöst] Android Script array value in if Abfrage verwenden.

droda

Newbie
Hallo allen miteinander,

Ich hoffe ich bin hierfür hier richtig, da ich dieses Script auf einem Android Handy nutze.

Zerfetzt bitte nicht gleich mein Script, ist mein aller erstes und tut bisher auch was es soll.
Aber bei meinem letzten unterfangen komme ich nicht mehr weiter.


Hier mein bisher funktionierendes Script.

Code:
#!/system/bin/sh

varr[100]=com.android.printspooler
varr[200]=com.android.email
varr[300]=com.android.bookmarkprovider


for i in "${varr[@]}"
do

if [[ $(cmd package list packages | grep $i | wc -l) = "1" ]] then
	# APP ist vorhanden
    if [[ $(pm path $i | sed 's/package://g' | grep -E ^\/system\/app\/ | wc -l) = 1 ]] || [[ $(pm path $i | sed 's/package://g' | grep -E ^\/system\/priv-app\/ | wc -l) = 1 ]] then
    	echo "System app"
    else
	if [[ $(cmd package list packages -d | grep $i | wc -l) = "1" ]] then
		echo "$i deaktiviert"
    	else	
    		echo "mache xyz"
 	   fi
 	fi
  else
  echo "$i ist ist nicht vorhanden"
fi

done

exit

Für eine weitere Auswertung brauche ich jetzt noch die Index Nr. des Arrays.
Nichts leichter als das... Dachte ich mir.
Etwas gesucht, schon etwas gefunden...


Code:
for i in ${!varr[*]}
do
    echo "$i"
    echo "${varr[$i]}"
    #test
    echo $(pm path ${varr[$i]} | sed 's/package://g' | grep -E ^\/system\/app\/ | wc -l) 
done

$i = ist der app Name.
${varr[$i]} = Die Index Nr.
Die test echo Ausgabe funktioniert hier auch.

Nun dachte ich mir...
Ändere ich die for... Zeile von for i in "${varr[@]}" in for i in ${!varr[*]} um und
ersetze meine vorherige $i in ${varr[$i]}.


Aber falsch gedacht...
Fehlermeldung.
: 100 200 300: unexpected '200'

Da es mit meinem Test Code funktioniert, würde ich nun sagen, der Fehler kommt deswegen
zustande, weil ich ${varr[$i]} in meine if Abfrage eingebaut habe.
Ich hab schon vieles probiert, Klammer mehr, Klammer weniger, bisher führte leider nichts zum Erfolg.

Könnte mir jemand noch hierfür den richtigen Denkanstoß geben.

Vielen Dank
 

framp

Moderator
Teammitglied
Nun dachte ich mir...
Ändere ich die for... Zeile von for i in "${varr[@]}" in for i in ${!varr[*]} um
Ist doch - fast - richtig :-D
Die Tuedelchen hast Du leider beim Ersetzen vergessen - und die sind hier wichtig ;)
 
OP
D

droda

Newbie
Hallo framp,

danke dir, ABER, war ein c&p fehler meinerseits.
Falls du die "" mit Tuedelchen meinst, diese waren vorhanden.

Ich hab es jetzt "ohne" Tuedelchen probiert. Und es läuft jetzt OHNE fehler durch...

ABER...

Jetzt schein es, als würde es ${varr[$i]} in der IF abfrage nicht richtig erkennen. Denn jetzt ist alles Falsch und es wird geich zu echo " echo "${varr[$i]} ist ist nicht vorhanden"

Hier aber im echo wird ${varr[$i]} richtig ausgegeben...

Sry
 
Bash unterstützt offiziell kein hash

Probier das:
Code:
for index in ${!varr[@]}; do
	printf "%d: %s\n" "$index" "${varr[$index]}"
done

Gruß
Gräfin Klara
 

framp

Moderator
Teammitglied
@gk Bash unterstuetzt ab Version 4 assoziative Arrays.

@droda Ich habe zugegebenermassen den Ueberblick verloren welchen Code Du genau (ohne Copy/Paste Fehler ;) ) ausfuehrst. Ein Tip zum debuggen von bash Scripts: Rufe das Script mit
Code:
bash -x <script>
auf. Vielleicht findest Du dann die Fehlerursache selbst :)
Ansonsten starte mal eine Script Session
Code:
script
und lass darin mal Deinen Code mit -xv laufen. Am Ende
Code:
exit
eingeben um die Script Session zu beenden und den Inhalt der Datei typescript hier mal posten.
 

abgdf

Guru
Gibt es auf Deinem System überhaupt bash? Du rufst ja sh auf.

Interessehalber: Gibt's da auch Perl und Python?

Ansonsten: Für den Anfang sehr gutes Skript! :thumbs:

In der Sache würde ich nicht versuchen, alles mit einer Variable zu regeln, sonst verheddert man sich.
Code:
#!/bin/bash

varr[100]=a
varr[200]=b
varr[300]=c

x=100
for i in "${varr[@]}"
do
    echo $x
    echo $i
    echo ${varr[$x]}
    let "x += 100"
done
"varr[100]" finde ich auch nicht so schön, das dürfte doch ein Array erzeugen mit 100 undefinierten Werten (von 0 bis 99), dann einen definierten. Muß das sein?
 
OP
D

droda

Newbie
Hallo und vielen Dank euch allen,

leider hat gestern, durch ein Gewitter, mein Router das zeitliche gesegnet. Erst jetzt konnte ich eine alternative in betrieb nehmen.

Erst mal danke nochmal für die vielen Tipps, vor allem das es eine debugging Möglichkeit gibt.

Mein Fehler war, ich hatte in der aller ersten IG Abfrage, noch ein $i vorhanden und hatte vergessen das mit ${varr[$i]} zu ersetzen. Als ich dies bemerkt und korrigiert hatte, lief das Script genau so wie ich es mir vorgestellt hatte durch.

Es war wirklich nur der Fehler, das die erste Variante mit
Code:
for i in "${varr[@]}"
lief und als ich dies auf
Code:
for i in "${!varr[*]}"
umgestellt hatte es nicht mehr ging...
Ich musste "einfach nur" die Tuedelchen entfernen und schon lief die Sache.

Immerhin dabei jetzt auch einige gute Tipps noch mitgenommen.

Vielen Dank nochmals.
 

uhelp

Member
Was ihr mit "Tüdelchen" meint, bleibt mir schleierhaft.

Aber ein paar Anmerkungen hätte ich da doch:

  • Ruft man eine Bash mit dem Shebang #!/bin/sh oder dergleichen auf, so verhält sich die Bash, wie eine Shell. Dort ist nur alte Syntax möglich, und es gibt noch ein paar sehr subtile Unterschiede zu der "echten Bash". Also lieber den Pfad explizit auf direkt setzen. (Welche Shell mit diesem Shellprompt wirklich gerufen wird, kann man nicht so ohne weiteres sagen. Assoziative Arrays funktionieren in diesem Posix-kompatiblen Shellmodus ganz sicher nicht, selbst wenn es eine echte Bash wäre, die man damit riefe.
  • Es ist stilistisch ziemlich verwirrend/schlecht die per Konvention zur numerischen Indexzählvariablen erklärte Variable "i" zu verwenden. Du hältst in dieser -eigentlich numerischen Variablen- Strings. Schreibe lieber sowas, wie for paket in "${Pakethaufen[@]}
  • Das Konstrukt ${!array[@]} nennen wir eine indirekte Expansion (siehe Codebeispiel weiter unten).
  • Der Unterschied zwischen "${array[@]}" (also mit Quotes) und ${array[@]}" (ohne Quotes) ist einfach.
    Das Quoting selbst muss verstanden sein, will man halbwegs brauchbare Scripte fabrizieren. Deshalb: Learn to quote!
    Enthält das Array "array" die Werte "eins zwei drei", so ergibt die Expansion OHNE Quotes drei Werte, nämlich eins zwei und drei.
    Ist die Expansion gequotet, so expandieren alles drei Strings zu EINEM String mit zwei Leerzeichen: "eins zwei drei".
    Damit dürfte dir der drastische Unterschied klar werden.
Ob du nun wirklich an den assoziativen Arrays scheiterst, wage ich stark zu bezweifeln. Du scheiterst eher an der Shell selbst, da nicht gewährleistet ist, dass es sich überhaupt um einen Bash handelt, die dort diesen Code ausführt. Und wenn es eine Shell wäre, so wären assoziatve Arrays immer noch nicht einsetzbar, weil es die eben im posixkompatiblen Shell- Modus gar nicht gibt. In egal welcher Version der Bash.

Es sei noch angemerkt, dass ein Konstrukt, wie ${array[$i]} schlechter Stil ist.
Denn bei "normalen" Arrays IST alles, was innerhalb der eckigen Klammern steht per definitionem ein numerischer Kontext.
Die Bash wird also automatisch den Buchstaben "i" als eine Variable ansehen, bei deren Inhalt sie automatisch alle Intermath ausführt.
Völlig legitim ist also ein Ausdruck, wie: ${array[i+3-z} wobei i und z gültige Integerwerte haben müssen. Die Expansion mit dem Dollarzeichen ist nicht nötig, und somit schlechter Stil.

Jetzt zur "Indirekten Expansion":
Code:
# ein paar Variablen definieren:
red='\033[1;31m'       # Escape- Sequenz für Farbe rot
green='\033[1;32m'    # der Käse in grün
color=      # Diese Zeile setzt die Variable "color" auf nada nothing not_yet_set
reset=$(tput reset)  # Käse zurücksetzen auf Standard

color=red    # wir setzen die color auf red
# und verweisen jetzt indirekt auf die tatsächlichen Farb- Escapesequenzen
printf "${!color}%s\n"   "Uhi, ist das aber rot"
color=green
printf "${!color}%s\n"   "Wie grünt so grün der Tannenbaum."
reset   # Farbkäse wieder ausschalten

# Bei Arrays bewirkt die Indirektion, dass bei assoziativen Arrays, die Keys ausgegeben werden,
# was bei numerisch indizierten Arrays eben die Indices sind.
 

uhelp

Member
Es scheint mir ziemlich einfältig Anführungszeichen einfältig zu nennen.
Wird wohl daran liegen, dass ich nicht aus dem Norden komme.

scnr.
 

framp

Moderator
Teammitglied
Mit einfaeltig hat das nichts zu tun. :wink:
zu Anfuehrungszeichen wikipedia schrieb:
Im Deutschen werden sie auch Anführungsstriche sowie umgangssprachlich auch Gänsefüßchen genannt, wobei dann die öffnenden Gänsefüßchen unten, die schließenden Gänsefüßchen oben heißen. In Norddeutschland ist umgangssprachlich „Tüddelchen“ (wohl zu mittelniederdeutsch „tud(d)er“: Seil zum Anbinden eines weidenden Tiers,[3] hier: „tüdern“ bzw. „anbinden“ eines zugehörigen Zeichens) gebräuchlich.[4] Die ähnliche standarddeutsch-umgangssprachliche Bezeichnung „Tüttelchen“ ist unspezifischer und kann – je nach Kontext – auch „Pünktchen“, „unwesentliche Kleinigkeit“ oder „Serife“ bedeuten.[5]
https://de.wikipedia.org/wiki/Anführungszeichen
 

abgdf

Guru
framp schrieb:
Mit einfaeltig hat das nichts zu tun. :wink:
zu Anfuehrungszeichen wikipedia schrieb:
Im Deutschen werden sie auch Anführungsstriche sowie umgangssprachlich auch Gänsefüßchen genannt, wobei dann die öffnenden Gänsefüßchen unten, die schließenden Gänsefüßchen oben heißen. In Norddeutschland ist umgangssprachlich „Tüddelchen“ (wohl zu mittelniederdeutsch „tud(d)er“: Seil zum Anbinden eines weidenden Tiers,[3] hier: „tüdern“ bzw. „anbinden“ eines zugehörigen Zeichens) gebräuchlich.[4] Die ähnliche standarddeutsch-umgangssprachliche Bezeichnung „Tüttelchen“ ist unspezifischer und kann – je nach Kontext – auch „Pünktchen“, „unwesentliche Kleinigkeit“ oder „Serife“ bedeuten.[5]
https://de.wikipedia.org/wiki/Anführungszeichen
Hmm, ja, wenn man so genau hinguckt, wird's kompliziert. :???:

Hier noch eine Theorie (von mir): Wenn einer etwas erzählt, das man nicht glauben kann, sagt man: "Ach, Du tüdelst doch". Im Sinne von "Das hast Du bestimmt nicht richtig verstanden" oder "Das hast Du bestimmt nicht richtig gehört", etwa, weil es nur eine "unwesentliche Kleinigkeit" war, bei der derjenige nicht richtig hingehört hat, als ein Dritter sie ihm erzählt hat (wobei man das Gesagte, wenn man es aufschreiben würde, in Anführungszeichen setzen würde).
Möglicherweise könnte es also einen Zusammenhang zwischen "Tüddelchen" und "tüdelig/tüdeln" geben. Aber etymologisch genau wird man's wohl nicht wissen. ;)
 

framp

Moderator
Teammitglied
Ich kenne tueddelig mit folgender Semantik: https://www.mundmische.de/bedeutung/34311-tueddelig sowie https://www.redensarten-index.de/suche.php?suchbegriff=~~t%C3%BCdelig%20%2F%20t%C3%BCddelig%20sein&bool=relevanz&suchspalte%5B%5D=rart_ou
 

uhelp

Member
Ich glaube, es ist allerhöchste Eisenbahn für ein fundiertes Quoting- Tutorial.

Das Quoting ist nämlich eben nicht tüdelig, sondern wirklich wesenziell, jawohl!
 

abgdf

Guru
Na ja, das Quoting in der Shell kommt eben daher, daß das Leerzeichen zur Trennung von Befehlen und Optionen verwendet wird, und man also z.B. kenntlich machen muß, wenn man in einem String wirklich ein Leerzeichen haben will. Die wesentlichen Fälle sind wohl:
Code:
#!/bin/bash
a="Hallo"
echo "Aber $a."
echo "Aber \$a."
echo "Aber \"$a\"."
echo 'Aber $a.'
Mich nervt das aber, auch z.B. Leerzeichen in Dateinamen. Perl hat dagegen überhaupt keine Probleme, damit umzugehen, weil es nicht auf die speziellen Leerzeichen in der Shell Rücksicht nehmen muß. Deshalb ziehe ich es vor, sobald es hauptsächlich darum geht, Daten zu verarbeiten. Da hat man dann auch ohne Probleme Arrays und assoziative Arrays (Hashes) zur Verfügung. Und z.B. eine leistungsfähige RegEx-Engine, ohne sich mit Pipes rumquälen zu müssen. Oder gar mit kaum vorhersehbarem Verhalten wegen Subshells.

Edit: Wahrscheinlich heißen die Anführungszeichen auch deshalb Tüddelchen, weil das alles mit ihnen so ein nerviges Rumgetüdel ist. ;)
 

uhelp

Member
Die Bash ist nun mal per definitionem ein Zwitterwesen.
Es ist ein Kommandopreter UND eine Scriptsprache.

Eine Shell mit einer "echten" Programmiersprache zu vergleichen, heißt Äpfel mit Raumschiffen zu vergleichen.
Statt solche Vergleiche anzustellen, könnte man die Bash einfach lernen.

Dann hat man auch Perl RegExes zur Hand.
Code:
var='Die Bash ist ein kompliziertes Tool, das aber viele Dinge einfach machen kann. Man kann selbstverständlich Perl Compatible Regexe verwenden.'

re_new_sentence='(Die) ([^ ]+ ist ein).+(Tool, das).+(viele Dinge einfach).+(kann).*'

[[ $var =~ $re_new_sentence ]]

printf "%s %s %s %s %s" "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" "${BASH_REMATCH[3]}" \
                        "${BASH_REMATCH[4]}" "${BASH_REMATCH[5]}" "${BASH_REMATCH[6]}"
 
Oben