2013-08-01 20 views
68

Próbuję zrobić skrypt, który powinien być używany tak:parametry skryptu bash

ocrscript.sh -from /home/kristoffer/test.png -to /home/kristoffer/test.txt 

Skrypt następnie OCR konwersji pliku obrazu do pliku tekstowego. Oto co mam wymyślić do tej pory:

#!/bin/bash 
export HOME=/home/kristoffer 
/usr/local/bin/abbyyocr9 -rl Swedish -if ???fromvalue??? -of ???tovalue??? 2>&1 

Ale ja nie wiem, jak uzyskać wartości -from i -to. Wszelkie pomysły, jak to zrobić?

+6

powinieneś przeczytać http://tldp.org/LDP/Bash-Beginners-Guide/html/Bash-Beginners-Guide.html –

+0

To jest znacznie lepszy post na ten temat: [Jak analizować argumenty wiersza poleceń w bash?] (http://stackoverflow.com/questions/18003370/script-parameters-in-bash) –

Odpowiedz

83

Argumenty podane w bashscriptu pojawią się w zmiennych $1 i $2 i $3, gdzie liczba odnosi się do argumentu. $0 to samo polecenie.

Argumenty są rozdzielone spacjami, więc jeśli chcesz zapewnić -from i -to w poleceniu, będą one skończyć w tych zmiennych też, więc na to:

./ocrscript.sh -from /home/kristoffer/test.png -to /home/kristoffer/test.txt 

Dostaniesz:

$0 # ocrscript.sh 
$1 # -from 
$2 # /home/kristoffer/test.png 
$3 # -to 
$4 # /home/kristoffer/test.txt 

To może być łatwiej pominąć -from i tym -to, jak:

ocrscript.sh /home/kristoffer/test.png /home/kristoffer/test.txt 

Wtedy będziesz mieć:

$1 # /home/kristoffer/test.png 
$2 # /home/kristoffer/test.txt 

Minusem jest to, że będziesz musiał dostarczyć je w odpowiedniej kolejności. Istnieją biblioteki, które mogą ułatwić analizowanie nazwanych argumentów w wierszu poleceń, ale zazwyczaj w przypadku prostych skryptów powłoki powinieneś po prostu użyć łatwej metody, jeśli nie stanowi to problemu.

Następnie można zrobić:

/usr/local/bin/abbyyocr9 -rl Swedish -if "$1" -of "$2" 2>&1 

podwójne cudzysłowy wokół $1 i $2 nie zawsze są konieczne, ale są adviced, ponieważ niektóre ciągi nie będzie działać, jeśli nie umieścić je między cudzysłów .

5

W bash $1 to pierwszy argument przekazany do skryptu, $2 sekund i tak dalej

/usr/local/bin/abbyyocr9 -rl Swedish -if "$1" -of "$2" 2>&1 

Więc można użyć:

./your_script.sh some_source_file.png destination_file.txt 

Wyjaśnienie na cudzysłów;

pod uwagę trzy scenariusze:

# foo.sh 
bash bar.sh $1 

# cat foo2.sh 
bash bar.sh "$1" 

# bar.sh 
echo "1-$1" "2-$2" 

Teraz przywołaj:

$ bash foo.sh "a b" 
1-a 2-b 

$ bash foo2.sh "a b" 
1-a b 2- 

Po wywołaniu foo.sh "a b" następnie wywołuje bar.sh a b (dwa argumenty), a także z foo2.sh "a b" wywołuje bar.sh "a b" (1 argument). Zawsze miej na uwadze, jak parametry są przekazywane i rozszerzane w bashu, to zaoszczędzi Ci wiele bólu głowy.

+0

Lovely! Dziękuję Ci!! – Kristoffer

21

Użyj zmiennych , "$2", "$3" i tak dalej, aby uzyskać dostęp do argumentów. Aby uzyskać dostęp do nich wszystkich, możesz użyć "[email protected]" lub uzyskać liczbę argumentów $# (może być przydatne sprawdzenie zbyt małej lub zbyt dużej liczby argumentów).

51

Jeśli nie jesteś całkowicie przywiązany do korzystania „z” i „do” jako nazwy opcji, jest to dość łatwe do wdrożenia tego używając getopts:

while getopts f:t: opts; do 
    case ${opts} in 
     f) FROM_VAL=${OPTARG} ;; 
     t) TO_VAL=${OPTARG} ;; 
    esac 
done 

getopts to program, który przetwarza argumenty wiersza poleceń i wygodnie je dla ciebie analizuje.

f:t: określa, że ​​oczekuje się 2 parametrów zawierających wartości (wskazane dwukropkiem). Coś takiego jak f:t:v mówi, że -v będzie interpretowane tylko jako flaga.

opts to miejsce, w którym przechowywany jest bieżący parametr. Oświadczenie case jest tam, gdzie to przetworzysz.

${OPTARG} zawiera wartość następującą po parametrze. ${FROM_VAL} na przykład dostanie wartość /home/kristoffer/test.png jeśli prowadził swój skrypt jak:

ocrscript.sh -f /home/kristoffer/test.png -t /home/kristoffer/test.txt

Jak inni sugerują, jeśli jest to twój pierwszy raz pisania skryptów bash należy naprawdę przeczytać na pewnych podstawach. To był tylko krótki samouczek na temat działania getopts.

+1

To wydaje się być czytelnym rozwiązaniem. Jak określiłbyś wtedy dwie flagi? – Zelphir

+0

@Zelphir, możesz podać dwie lub więcej flag po prostu ommiting ":" po flagę. Na przykład 'f: t: vs' będzie' -f some_f -t some_t -v -s' –

14

Musiałem się upewnić, że moje skrypty są całkowicie przenośne między różnymi maszynami, powłokami, a nawet wersjami cygwin. Ponadto, moi koledzy, którzy byli tymi miałem pisać skrypty dla, to programiści, więc skończyło się przy użyciu to:

for ((i=1;i<=$#;i++)); 
do 

    if [ ${!i} = "-s" ] 
    then ((i++)) 
     var1=${!i}; 

    elif [ ${!i} = "-log" ]; 
    then ((i++)) 
     logFile=${!i}; 

    elif [ ${!i} = "-x" ]; 
    then ((i++)) 
     var2=${!i};  

    elif [ ${!i} = "-p" ]; 
    then ((i++)) 
     var3=${!i}; 

    elif [ ${!i} = "-b" ]; 
    then ((i++)) 
     var4=${!i}; 

    elif [ ${!i} = "-l" ]; 
    then ((i++)) 
     var5=${!i}; 

    elif [ ${!i} = "-a" ]; 
    then ((i++)) 
     var6=${!i}; 
    fi 

done; 

Uzasadnienie: I obejmował launcher.sh skrypt, jak również, ponieważ cała operacja miała kilka etapów które były niemalże niezależne od siebie (mówię "quasi", ponieważ chociaż każdy skrypt mógł być uruchamiany samodzielnie, zwykle były one prowadzone razem), aw ciągu dwóch dni dowiedziałem się, że około połowa moich kolegów , będąc programistami i wszystkimi, byli zbyt dobrzy, aby używać pliku programu uruchamiającego, śledzić "użycie" lub przeczytać HELP, która była wyświetlana za każdym razem, gdy zrobili coś złego i robili bałagan na całość, uruchamiając skrypty z argumentami w złej kolejności i narzekając, że skrypty nie działają poprawnie. Będąc choleryczką, postanowiłem przerobić wszystkie moje skrypty, aby upewnić się, że są kolektywne. Powyższy segment kodu był pierwszą rzeczą.

+1

Podoba mi się to. Dodaję sekcję na końcu 'else echo" Niepoprawny argument: $ {! I} " ((+++)) fi ' – CJBS

+0

Preferuję to rozwiązanie. jest czytelny i łatwy w użyciu. –