Pytanie Parametry skryptu w Bash


Próbuję utworzyć skrypt powłoki, który powinien być używany w następujący sposób:

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

Skrypt następnie przekształci plik obrazu w plik tekstowy. Oto, co do tej pory wymyśliłem:

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

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


76
2017-08-01 19:57


pochodzenie


powinieneś czytać tldp.org/LDP/Bash-Beginners-Guide/html/... - Mehul Rathod
Jest to znacznie lepszy post na ten temat: Jak analizować argumenty linii poleceń w bashu? - Igor Fobia


Odpowiedzi:


Argumenty podane w bashscriptu pojawią się w zmiennych $1 i $2 i $3 gdzie liczba odnosi się do argumentu. $0 jest samą komendą.

Argumenty są oddzielone spacjami, więc jeśli chcesz podać -from i -to w poleceniu będą one również kończyć się tymi zmiennymi, więc:

./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

Łatwiej byłoby pominąć -from i -to, lubić:

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ć go we właściwej 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żesz zrobić:

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

Podwójne cytaty wokół $1 i $2 nie zawsze są konieczne, ale są zalecane, ponieważ niektóre ciągi nie będą działać, jeśli nie umieścisz ich między podwójnymi cudzysłowami.


90
2017-08-01 20:09





Jeśli nie jesteś całkowicie przywiązany do używania "od" i "do" jako swoich nazw opcji, dość łatwo jest zaimplementować to za pomocą 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 analizuje.

f:t: określa, że ​​oczekujesz 2 parametrów, które zawierają wartości (wskazane przez dwukropek). Coś jak f:t:v mówi że -v będzie interpretowany tylko jako flaga.

opts jest tam, gdzie przechowywany jest bieżący parametr. The case oświadczenie to miejsce, w którym będziesz to przetwarzać.

${OPTARG} zawiera wartość następującą po parametrze. ${FROM_VAL} na przykład otrzyma wartość /home/kristoffer/test.png jeśli uruchomiłeś skrypt w następujący sposób:

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

Jak sugerują inni, jeśli po raz pierwszy piszesz skrypty bash, powinieneś naprawdę zapoznać się z podstawami. To był tylko krótki samouczek getopts Prace.


55
2017-08-01 20:17



To wydaje się być czytelnym rozwiązaniem. Jak określiłbyś wtedy dwie flagi? - Zelphir
@Zelphir, możesz określić 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 - h_s


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


25
2017-08-01 20:13





Musiałem się upewnić, że moje skrypty są całkowicie przenośne między różnymi maszynami, powłokami, a nawet wersjami cygwin. Co więcej, moi koledzy, których musiałem napisać skrypty, są programistami, więc w końcu skorzystałem z tego:

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: zawarłem a launcher.sh Skrypt również, ponieważ cała operacja miała kilka kroków, które były quasi niezależne od siebie (mówię "quasi", ponieważ mimo tego, że każdy skrypt mógł być uruchamiany na własną rękę, były one zazwyczaj uruchamiane razem), a w dwóch dni dowiedziałem się, że około połowa moich kolegów, którzy są programistami i wszyscy, była zbyt dobra, aby używać pliku launchera, ś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 w całej sprawie, uruchamianie skryptów z argumentami w niewłaściwej kolejności i narzekanie, ż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ą.


15
2017-07-06 14:55



Lubię to. Dodaję sekcję na końcu `else echo" Nieprawidłowy argument: $ {! I} "((++)) fi` - CJBS
Preferuję to rozwiązanie. jest czytelny i łatwy w użyciu. - Christian Noel


W bash $1 jest pierwszym argumentem przekazanym do skryptu, $2 drugi i tak dalej

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

Możesz więc użyć:

./your_script.sh some_source_file.png destination_file.txt

Wyjaśnienie podwójnych cytatów;

rozważ trzy skrypty:

# foo.sh
bash bar.sh $1

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

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

Teraz wywołaj:

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

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

Kiedy się powołujesz foo.sh "a b" następnie wywołuje bar.sh a b (dwa argumenty) i z foo2.sh "a b" przywoł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.


6
2017-08-01 20:02



Śliczny! Dziękuję Ci!! - Kristoffer