mboost-dp1

Shell script til android


Gå til bund
Gravatar #1 - Qw_freak
30. maj 2012 08:03
hey, jeg er igang med at sammenligen strenge i et script, men på min device kan den ikke forstå '=' og '==' operatorerne, why?

Og hvordan kan man ellers sammenligne to strenge i et shell script i android kernel?

det jeg har nu:

#!/system/bin/bash
#
# Script to toggle between active and inactive adb on the device
#
# Recieves parameter start or stop to toggle adb
#
# use: adb_toggle.sh start
# adb_toggle.sh stop
#
#
parameter=$1
#
if ( $1 = "start" ); then
#
start adbd
#echo "adbd is to start"
#
#
elif ( $1 = "stop" ); then
#
stop adbd
#echo "adbd is to be stopped"
#
else
#
echo "Your parameer was: " $parameter
echo "Wrong parameter, use start or stop"
#
fi
Gravatar #2 - Brugernavn
30. maj 2012 08:45
Jeg lægger mærke til at andre shell scripts, jeg har set, har dobbelte lighedstegn til sammenligning og firkatparanteser i stedet for almindelige paranteser...
Gravatar #3 - Qw_freak
30. maj 2012 08:57
Brugernavn (2) skrev:
Jeg lægger mærke til at andre shell scripts, jeg har set, har dobbelte lighedstegn til sammenligning og firkatparanteser i stedet for almindelige paranteser...


Yep, men firkantparanteser vil android ikke genkende, og jeg har prøvet med dobbelt lighedstagen...
Gravatar #4 - myplacedk
30. maj 2012 08:57
Det er almindelig bash, det har intet med Android at gøre. :)

Prøv med firkantede parenteser, og husk at quote:

if [ "$a" = "$b" ]

Hvis dit script bliver kaldt uden parameter, eller en tom streng som første parameter, bliver det til:

if [ $1 = "start" ];
=>
if [ = "start" ];
=>
syntax fejl

if [ "$1" = "start" ];
=>
if [ "" = "start" ];
=>
false

Der er masser af eksempler her: http://tldp.org/LDP/abs/html/comparison-ops.html

Gravatar #5 - myplacedk
30. maj 2012 08:57
Qw_freak (3) skrev:
Yep, men firkantparanteser vil android ikke genkende

Hvad får dig til at sige det?
Gravatar #6 - myplacedk
30. maj 2012 09:10
Qw_freak (3) skrev:
firkantparanteser vil android ikke genkende

Virker fint her:

http://i.imgur.com/pHhgW.png
Gravatar #7 - Qw_freak
30. maj 2012 09:39
well, så kna jeg ikke se fejlen...
http://peecee.dk/uploads/052012/Scriptfail_big_thu...



myplacedk (4) skrev:
Der er masser af eksempler her: http://tldp.org/LDP/abs/html/comparison-ops.html


Har skam været der... :)

Gravatar #8 - kasperd
30. maj 2012 09:45
Qw_freak (7) skrev:
well, så kna jeg ikke se fejlen...
http://peecee.dk/uploads/052012/Scriptfail_big_thu...
Den er for nem den der. Der mangler mellemrum omkring [ og ]
Gravatar #9 - Qw_freak
30. maj 2012 09:52
kasperd (8) skrev:
Den er for nem den der. Der mangler mellemrum omkring [ og ]


Desværre, med mellemrum kommer samme fejl,. bare uden start:

før: [start: not found
nu: [: not found
Gravatar #10 - fjols
30. maj 2012 09:56
Nogen speciel grund til du bruger sh til at starte et bash script med?
Ikke at jeg tror det løser nogen problemer, undrer mig bare :)
Gravatar #11 - Qw_freak
30. maj 2012 09:59
fjols (10) skrev:
Nogen speciel grund til du bruger sh til at starte et bash script med?
Ikke at jeg tror det løser nogen problemer, undrer mig bare :)


Ja, jeg kender ikke lige andre måder at køre det på.. ./ virker ikke...


Gravatar #12 - fjols
30. maj 2012 10:01
bash adb_toggle.sh start


;)
Gravatar #13 - myplacedk
30. maj 2012 10:05
Qw_freak (11) skrev:
jeg kender ikke lige andre måder at køre det på


bash script.sh # kører det i bash
. script.sh # kører det i den shell du allerede er i
chmod +x script.sh # gør at du for eftertiden kan starte med ./script.sh

Gravatar #14 - myplacedk
30. maj 2012 10:06
Qw_freak (9) skrev:
kasperd (8) skrev:
Den er for nem den der. Der mangler mellemrum omkring [ og ]


Desværre, med mellemrum kommer samme fejl,. bare uden start:

Hvordan ser din kode ud nu? (Jeg gætter på en anden syntax fejl)
Gravatar #15 - Qw_freak
30. maj 2012 10:34
myplacedk (14) skrev:

Hvordan ser din kode ud nu? (Jeg gætter på en anden syntax fejl)


#!/system/bin/bash
#
# Script to toggle between active and inactive adb on the device
#
# Recieves parameter start or stop to toggle adb
#
# use: adb_toggle.sh start
# adb_toggle.sh stop
#
#
parameter=$1
#
if [ "$1" = "start" ]; then
#
start adbd
#echo "adbd is to start"
#
#
elif [ "sh $1" = "stop" ]; then
#
stop adbd
#echo "adbd is to be stopped"
#
else
#
echo "Your parameer was: " $parameter
echo "Wrong parameter, use start or stop"
#
fi



Gravatar #16 - kasperd
30. maj 2012 11:16
Qw_freak (9) skrev:
[: not found
[workaround for bugs i newz parser, hvem var det fjols der fandt på at udskifte html med noget der er umuligt at parse korrekt]
Så er det nok ikke en bash du kører scriptet i. Men #10 har allerede påpeget hvilken fejl der forårsagede det.

myplacedk (13) skrev:
. script.sh # kører det i den shell du allerede er i
Der skal man så lige være opmærksom på at selvom man allerede kører bash, så er der stor forskel på at køre "bash script.sh" og ". script.sh" fordi den første starter en ny instans af bash og . bruger den nuværende instans.

Som regel er man interesseret i en ny instans, og hvis man er interesseret i at bruge samme instans, er det fordi man har et helt specifikt formål med det.

Qw_freak (15) skrev:
elif [ "sh $1" = "stop" ]; then
Selvom den linie ikke ser ud til at have nogen syntaksfejl, så gør den ikke hvad du havde tænkt dig. Uanset værdien af $1, så kan det udtryk aldrig blive sandt fori h og t er to forskellige bogstaver.
Gravatar #17 - Qw_freak
30. maj 2012 11:31
kasperd (16) skrev:
Qw_freak (15) skrev:
elif [ "sh $1" = "stop" ]; then
Selvom den linie ikke ser ud til at have nogen syntaksfejl, så gør den ikke hvad du havde tænkt dig. Uanset værdien af $1, så kan det udtryk aldrig blive sandt fori h og t er to forskellige bogstaver.


ahh, det er bare en tastefejl, der skal stå:
elif [ "$1" = "stop" ]; then
**

**virker ikke uden fejlen
Gravatar #18 - fjols
30. maj 2012 11:39
Det virker fint her på alle tænkelige måder.

Lige en betragtning mere, du skriver " start" på billedet. Dette virker dog fint i min shell, så det er nok endnu en blindgyde.

Virker dit script hvis du kommenterer "stop adbd" og "start adbd" ud og i stedet udkommenterer echo linierne?
Gravatar #19 - myplacedk
30. maj 2012 11:49
Jeg er enig, jeg ser ingen fejl ud over det kasperd nævnte. Men da du tilsyneladende skriver det af i stedet for at kopiere siger det ikke noget 100%.

Men...

[: not found

Sådan siger bash normalt ikke. For det første, så ville jeg forvente noget i stil med:

adb_toggle.sh: line 13: [: command not found

For det andet er "[" en built-in commandi bash, og kan dermed ikke bliver væk. Altså - det ligner ikke bash

Starter du med "./adb_toggle.sh"? Hvad siger den, hvis du kører "/system/bin/bash --version"?
Gravatar #20 - Qw_freak
30. maj 2012 11:54
kan desværre ikke lige få det til at køre lige nu, da mit board er blevet sendt ud af huset...


:(
Gravatar #21 - kasperd
30. maj 2012 17:18
myplacedk (19) skrev:
Altså - det ligner ikke bash

Starter du med "./adb_toggle.sh"? Hvad siger den, hvis du kører "/system/bin/bash --version"?
Enig, der er intet som tyder på at det er bash. Det vil være interessant at se hvad /system/bin/bash --version siger. Det vil overhovedet ikke være overraskende hvis det viser sig at være en helt anden shell.

Hvad får så nogen til at lave en /system/bin/bash som slet ikke er nogen bash? Det kan have været en smutter med nogle symlinks. F.eks. kan man have lavet /bin/sh som symlink til /system/bin/bash og efterfølgende prøvet at overskrive /bin/sh med en anden shell, og derved have overskrevet /system/bin/bash.

Det kan også være man har lavet /system/bin/bash som et symlink til en anden shell i første omgang, vel vidende at det ikke er nogen bash. Det ville være en elendig praksis, men det kunne have været en workaround for noget som forventede at bash var en gyldig kommando.

Hvis noget kalder bash og ikke f.eks. /bin/sh, så er det nok fordi det anvender bash features. Hvis det lige så vel kunne have brugt /bin/sh i stedet for bash, så er løsningen ikke at lave et symlink der hedder bash, men derimod at rette det program der kalder bash når /bin/sh ville have været tilstrækkeligt.

For /bin/sh er der nogle ret præcise krav til hvad der skal være af features og indbyggede kommandoer. Det er vist tilladt at have ekstra features i /bin/sh så længe de ikke ændrer på de obligatoriske features. Men på den anden side er det nok smartere at /bin/sh ikke udstyres med ekstra features i første omgang, da det blot betyder at nogen kan komme til at bruge dem ved en fejltagelse og dermed lave et script der bruger /bin/sh hvor det faktisk kræver bash.

bash har alle de features der kræves af en /bin/sh og en del ekstra. Hvis man kalder bash med navnet sh (f.eks. ved at lade /bin/sh være et link til bash), så slår bash nogle af sine features fra. Jeg ved ikke om det er for at overholde standarden eller blot for at man ikke ved et uheld bruger de features, hvor man ikke burde.

Hvad angår de mange forskellige måder som er blevet nævnt til at starte et shell script på, så er de fleste kombinationsmuligheder kun beregnet til test eller internt brug. Og der er i sidste ende kun to metoder som bør bruges i praksis. Den ene metode er til shell scripts, den anden metode er til rc filer eller includes til shell scripts.

Et shell script skal have execute bitten sat. Det vil sige ulige tal i en chmod kommando, som f.eks. "chmod 755 script.sh" eller "chmod 700 script.sh". Et shell script skal starte med #!/sti/til/shell

De første tre tegn i filen skal være #!/ altså ingen linieskift før og ingen mellemrum imellem. Når man kalder et script gøres det på samme måde som med en programfil. Den der kalder må ikke bekymre sig om hvorvidt det der kaldes er en programfil eller et script. Brug af ". script.sh" eller "shellnavn script.sh" er kun til at eksperimentere med.

En rc fil eller en include fil bør ikke have execute bitten sat. Det vil sige lige tal i en chmod kommando som f.eks. "chmod 644 script.sh" eller "chmod 600 script.sh"

Sådan en fil bør ikke starte med #!. Det er fornuftigt at starte med en kommentar der beskriver filens formål. Det vil sige at den må gerne starte med et # tegn. Man skal bare bruge noget andet end ! som det andet tegn. Det er fornuftigt nok at starte med et # tegn efterfulgt af et mellemrum.

Hvis man på trods af manglende execute bit og manglende #! i starten af filen alligevel præsterer at køre den som om den var et script, så bør filens øvrige indhold være konstrueret så scriptet reelt intet gør. Det vil nok definere en række environment variable og shell funktioner, men i sidste ende ikke bruge dem til noget og afslutte uden at have udrettet noget.

Der er forskellige korrekte måder at bruge sådan en fil på. Den kan f.eks. indlæses automatisk ved start af en shell. Det kan f.eks. være med et navn som:
~/.bashrc
/etc/bashrc
/etc/profile

Den kan også indlæses manuelt ved at bruge . kommandoen fra sin shell. Man kan ved kommandolinien indtaste ". navn-på-rc-fil". Denne måde at indlæse en rc-fil på er mest for power-users.

Den kan også indlæses fra et script eller fra en anden rc-fil ved at bruge . kommandoen. F.eks. indeholder min .bashrc kommandoen: ". ~/.bash_aliases" og mange scripts under /etc/init.d indeholder en kommando i stil med ". /lib/lsb/init-functions"

Man skal altså gøre op med sig selv om det man skriver er et script eller en rc-fil og så gøre det rigtige på de fire punkter, hvor de to bør afvige. Det du er ved at skrive er et script, så vi skal blot sikre at du gør det rigtige med hensyn til at få det afviklet som sådan.
Gravatar #22 - kasperd
30. maj 2012 18:56
Jeg undersøgte lige mine egne Android telefoner. Der er ingen /system/bin/bash på dem.

Nogle shells har workarounds hvis man laver et script uden en #! linie i starten. Den slags workarounds er dumme. Et script uden #! i starten er en fejl. At shells laver en workaround gør blot fejlene sværere at opdage og rette.

Man kan sagtens komme ud for at to forskellige shells har forskellige workarounds for manglende #! linie. Så bliver scriptet afviklet under forskellig shell afhængig af hvordan man kalder det. Og scriptet virker sandsynligvis kun korrekt i den ene. Den slags er ikke lige så åbenlyst som hvis man blot med det samme havde fået en fejlmelding om ugyldigt executable format.

Jeg spekulerer nu på om der findes nogen shells som er gået så vidt at lave en workaround for scripts med en #! linie der referer en ikke eksisterende shell. Tænk hvis den shell man kalder scriptet fra blot vælger at afvikle scriptet med en anden shell, hvis /system/bin/bash ikke findes.

Det er ikke umuligt, men ville være dybt tåbeligt. Den mulighed er der selvfølgelig ingen grund til at undersøge endnu. Først skal det undersøges hvad /system/bin/bash --version siger.
Gravatar #23 - Qw_freak
30. maj 2012 19:10
kasperd (22) skrev:
Jeg undersøgte lige mine egne Android telefoner. Der er ingen /system/bin/bash på dem.


Det er der på den kernel jeg arbejder på, og der er også en sh...
Gravatar #24 - kasperd
30. maj 2012 20:22
Qw_freak (23) skrev:
Det er der på den kernel jeg arbejder på
Nej. Kerne og shell er to forskellige ting.
Det du mener er at det Android build du arbejder på har en bash. Og så må vi finde ud af om det nu også er rigtigt, for intet af det du har vist os indtil nu ligner en bash. Men det lyder ikke som om vi kommer videre før du har fået din hardware tilbage.
Gravatar #25 - Qw_freak
30. maj 2012 21:05
kasperd (24) skrev:
Qw_freak (23) skrev:
Det er der på den kernel jeg arbejder på
Nej. Kerne og shell er to forskellige ting.
Det du mener er at det Android build du arbejder på har en bash. Og så må vi finde ud af om det nu også er rigtigt, for intet af det du har vist os indtil nu ligner en bash. Men det lyder ikke som om vi kommer videre før du har fået din hardware tilbage.

Okay, der er nok noget philosofi omkring kernel/bash/shell/script, jeg skal ha styr på... :9

Jeg får min HW tilbage mandag, tror jeg... EMC test...

Gravatar #26 - kasperd
30. maj 2012 22:02
Qw_freak (25) skrev:
Okay, der er nok noget philosofi omkring kernel/bash/shell/script, jeg skal ha styr på
Kernen er den vmlinuz fil der indlæses under opstart og de drivere der indlæses som moduler i kernen derefter. Moduler har siden 2.6 været i .ko format, det står for kernel object.

En shell er et program ligesom så mange andre. Der er ikke nogen entydig linie der adskiller shells fra andre programmer. Der kan altså sagtens være grænsetilfælde hvor det ikke er klart om et program er en shell eller ej. Der er dog tilfælde hvor der ikke er nogen tvivl. F.eks. er bash helt klart en shell, imens xclock ikke er nogen shell.

Nogle karakteristika ved en shell er at det er et kommandolinie program som indlæser kommandoer fra stdin (med mindre det er instrueret til at bruge en script fil i stedet), og at kommandoerne kan bruges til at starte andre programmer.

Programfiler kan have et antal forskellige formater, mest udbredt er ELF. Et script er en programfil af et format hvor der gælder lidt anderledes regler for end andre programfiler. Et script starter altid med #! efterfulgt af navnet på en programfil. Denne programfil kaldes for en interpreter eller en fortolker, hvis du vil have et dansk navn for det. Hvis fortolkeren er en shell, så er scriptet et shell script.

Hvis man f.eks. ikke vil kalde perl for en shell, og man har et script der starter med #!/usr/bin/perl, så er det ikke et shell script. Det er stadig et script, mere specifikt et perl script.

Efter navnet på en interpreter kan scriptet have et mellemrum efterfulgt af et enkelt argument til fortolkeren. Derefter kommer der et linieskift.

Det som kernen gør når man kalder et script er at lave om på exec argumenterne. Det tilføjer fortolkerens navn og det ene argument, hvis du har angivet et, foran navnet på scriptet. Og så kører kernen den resulterende kommando i stedet for.

Hvis man f.eks. har /usr/local/bin/myscript som starter med #!/bin/bash -e, og kører "/usr/local/bin/myscript" "arg1" "arg2", så vil kernen i stedet køre "/bin/bash" "-e" "/usr/local/bin/myscript" "arg1" "arg2"

Det er faktisk alt hvad kernen foretager sig omkring scripts. Bemærk at fortolkeren ikke selv må være et script. Det er vist bare for at undgå spørgsmål om hvor mange niveauer af scripts man må bruge. Egentlig kunne man nok lige så godt have tilladt scripts i så mange niveauer man har lyst til indtil kommandolinien overstiger maksimumslængden.
Gå til top

Opret dig som bruger i dag

Det er gratis, og du binder dig ikke til noget.

Når du er oprettet som bruger, får du adgang til en lang række af sidens andre muligheder, såsom at udforme siden efter eget ønske og deltage i diskussionerne.

Opret Bruger Login